ai-pipeline-core 0.1.13__py3-none-any.whl → 0.1.14__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,7 @@ from __future__ import annotations
10
10
 
11
11
  import datetime
12
12
  import inspect
13
+ from functools import wraps
13
14
  from typing import (
14
15
  Any,
15
16
  Callable,
@@ -36,7 +37,7 @@ from typing_extensions import TypeAlias
36
37
 
37
38
  from ai_pipeline_core.documents import DocumentList
38
39
  from ai_pipeline_core.flow.options import FlowOptions
39
- from ai_pipeline_core.tracing import TraceLevel, trace
40
+ from ai_pipeline_core.tracing import TraceLevel, set_trace_cost, trace
40
41
 
41
42
  # --------------------------------------------------------------------------- #
42
43
  # Public callback aliases (Prefect stubs omit these exact types)
@@ -224,6 +225,7 @@ def pipeline_task(
224
225
  trace_ignore_inputs: list[str] | None = None,
225
226
  trace_input_formatter: Callable[..., str] | None = None,
226
227
  trace_output_formatter: Callable[..., str] | None = None,
228
+ trace_cost: float | None = None,
227
229
  # prefect passthrough
228
230
  name: str | None = None,
229
231
  description: str | None = None,
@@ -263,6 +265,7 @@ def pipeline_task(
263
265
  trace_ignore_inputs: list[str] | None = None,
264
266
  trace_input_formatter: Callable[..., str] | None = None,
265
267
  trace_output_formatter: Callable[..., str] | None = None,
268
+ trace_cost: float | None = None,
266
269
  # prefect passthrough
267
270
  name: str | None = None,
268
271
  description: str | None = None,
@@ -316,6 +319,9 @@ def pipeline_task(
316
319
  trace_ignore_inputs: List of parameter names to exclude from tracing.
317
320
  trace_input_formatter: Custom formatter for input tracing.
318
321
  trace_output_formatter: Custom formatter for output tracing.
322
+ trace_cost: Optional cost value to track in metadata. When provided and > 0,
323
+ sets gen_ai.usage.output_cost, gen_ai.usage.cost, and cost metadata.
324
+ Also forces trace level to "always" if not already set.
319
325
 
320
326
  Prefect task parameters:
321
327
  name: Task name (defaults to function name).
@@ -405,6 +411,19 @@ def pipeline_task(
405
411
  )
406
412
 
407
413
  fname = _callable_name(fn, "task")
414
+
415
+ # Create wrapper to handle trace_cost if provided
416
+ @wraps(fn)
417
+ async def _wrapper(*args: Any, **kwargs: Any) -> R_co:
418
+ result = await fn(*args, **kwargs)
419
+ if trace_cost is not None and trace_cost > 0:
420
+ set_trace_cost(trace_cost)
421
+ return result
422
+
423
+ # Preserve the original function name for Prefect
424
+ _wrapper.__name__ = fname
425
+ _wrapper.__qualname__ = getattr(fn, "__qualname__", fname)
426
+
408
427
  traced_fn = trace(
409
428
  level=trace_level,
410
429
  name=name or fname,
@@ -413,7 +432,7 @@ def pipeline_task(
413
432
  ignore_inputs=trace_ignore_inputs,
414
433
  input_formatter=trace_input_formatter,
415
434
  output_formatter=trace_output_formatter,
416
- )(fn)
435
+ )(_wrapper)
417
436
 
418
437
  return cast(
419
438
  _TaskLike[R_co],
@@ -463,6 +482,7 @@ def pipeline_flow(
463
482
  trace_ignore_inputs: list[str] | None = None,
464
483
  trace_input_formatter: Callable[..., str] | None = None,
465
484
  trace_output_formatter: Callable[..., str] | None = None,
485
+ trace_cost: float | None = None,
466
486
  # prefect passthrough
467
487
  name: str | None = None,
468
488
  version: str | None = None,
@@ -497,6 +517,7 @@ def pipeline_flow(
497
517
  trace_ignore_inputs: list[str] | None = None,
498
518
  trace_input_formatter: Callable[..., str] | None = None,
499
519
  trace_output_formatter: Callable[..., str] | None = None,
520
+ trace_cost: float | None = None,
500
521
  # prefect passthrough
501
522
  name: str | None = None,
502
523
  version: str | None = None,
@@ -557,6 +578,9 @@ def pipeline_flow(
557
578
  trace_ignore_inputs: Parameter names to exclude from tracing.
558
579
  trace_input_formatter: Custom input formatter.
559
580
  trace_output_formatter: Custom output formatter.
581
+ trace_cost: Optional cost value to track in metadata. When provided and > 0,
582
+ sets gen_ai.usage.output_cost, gen_ai.usage.cost, and cost metadata.
583
+ Also forces trace level to "always" if not already set.
560
584
 
561
585
  Prefect flow parameters:
562
586
  name: Flow name (defaults to function name).
@@ -666,6 +690,8 @@ def pipeline_flow(
666
690
  **kwargs: Any,
667
691
  ) -> DocumentList:
668
692
  result = await fn(project_name, documents, flow_options, *args, **kwargs)
693
+ if trace_cost is not None and trace_cost > 0:
694
+ set_trace_cost(trace_cost)
669
695
  if not isinstance(result, DocumentList): # pyright: ignore[reportUnnecessaryIsInstance]
670
696
  raise TypeError(
671
697
  f"Flow '{fname}' must return DocumentList, got {type(result).__name__}"
@@ -35,6 +35,7 @@ Note:
35
35
  of each document type for consistent organization.
36
36
  """
37
37
 
38
+ import json
38
39
  from pathlib import Path
39
40
  from typing import Any, Callable, Sequence, Type
40
41
 
@@ -113,9 +114,20 @@ def load_documents_from_directory(
113
114
  if not file_path.is_file() or file_path.name.endswith(Document.DESCRIPTION_EXTENSION):
114
115
  continue
115
116
 
117
+ # Skip .sources.json files - they are metadata, not documents
118
+ if file_path.name.endswith(".sources.json"):
119
+ continue
120
+
116
121
  try:
117
122
  content = file_path.read_bytes()
118
- doc = doc_class(name=file_path.name, content=content)
123
+
124
+ # Load sources if .sources.json exists
125
+ sources = []
126
+ sources_file = file_path.with_name(file_path.name + ".sources.json")
127
+ if sources_file.exists():
128
+ sources = json.loads(sources_file.read_text(encoding="utf-8"))
129
+
130
+ doc = doc_class(name=file_path.name, content=content, sources=sources)
119
131
 
120
132
  desc_file = file_path.with_name(file_path.name + Document.DESCRIPTION_EXTENSION)
121
133
  if desc_file.exists():
@@ -185,6 +197,11 @@ def save_documents_to_directory(base_dir: Path, documents: DocumentList) -> None
185
197
  desc_file = file_path.with_name(file_path.name + Document.DESCRIPTION_EXTENSION)
186
198
  desc_file.write_text(document.description, encoding="utf-8")
187
199
 
200
+ # Save sources to .sources.json if present
201
+ if document.sources:
202
+ sources_file = file_path.with_name(file_path.name + ".sources.json")
203
+ sources_file.write_text(json.dumps(document.sources, indent=2), encoding="utf-8")
204
+
188
205
 
189
206
  async def run_pipeline(
190
207
  flow_func: Callable[..., Any],
@@ -15,7 +15,7 @@ import os
15
15
  from functools import wraps
16
16
  from typing import Any, Callable, Literal, ParamSpec, TypeVar, cast, overload
17
17
 
18
- from lmnr import Instruments, Laminar, observe
18
+ from lmnr import Attributes, Instruments, Laminar, observe
19
19
  from pydantic import BaseModel
20
20
 
21
21
  from ai_pipeline_core.settings import settings
@@ -370,7 +370,7 @@ def trace(
370
370
  # Store the new parameters
371
371
  _session_id = session_id
372
372
  _user_id = user_id
373
- _metadata = metadata
373
+ _metadata = metadata or {}
374
374
  _tags = tags or []
375
375
  _span_type = span_type
376
376
  _ignore_input = ignore_input
@@ -404,10 +404,8 @@ def trace(
404
404
  observe_params["session_id"] = _session_id
405
405
  if _user_id:
406
406
  observe_params["user_id"] = _user_id
407
-
408
- # Merge decorator-level metadata and tags
409
407
  if _metadata:
410
- observe_params["metadata"] = {**observe_params.get("metadata", {}), **_metadata}
408
+ observe_params["metadata"] = _metadata
411
409
  if _tags:
412
410
  observe_params["tags"] = observe_params.get("tags", []) + _tags
413
411
  if _span_type:
@@ -473,4 +471,113 @@ def trace(
473
471
  return decorator # Called as @trace(...)
474
472
 
475
473
 
476
- __all__ = ["trace", "TraceLevel", "TraceInfo"]
474
+ def set_trace_cost(cost: float | str) -> None:
475
+ """Set cost attributes for the current trace span.
476
+
477
+ Sets cost metadata in the current LMNR trace span for tracking expenses
478
+ of custom operations. This function should be called within a traced
479
+ function to dynamically set or update the cost associated with the
480
+ current operation. Particularly useful for tracking costs of external
481
+ API calls, compute resources, or custom billing scenarios.
482
+
483
+ The cost is stored in three metadata fields for compatibility:
484
+ - gen_ai.usage.output_cost: Standard OpenAI cost field
485
+ - gen_ai.usage.cost: Alternative cost field
486
+ - cost: Simple cost field
487
+
488
+ Args:
489
+ cost: The cost value to set. Can be:
490
+ - float: Cost in dollars (e.g., 0.05 for 5 cents)
491
+ - str: USD format with dollar sign (e.g., "$0.05" or "$1.25")
492
+ Only positive values will be set; zero or negative values are ignored.
493
+
494
+ Example:
495
+ >>> # Track cost of external API call
496
+ >>> @trace
497
+ >>> async def call_translation_api(text: str) -> str:
498
+ ... # External API charges per character
499
+ ... char_count = len(text)
500
+ ... cost_per_char = 0.00001 # $0.00001 per character
501
+ ...
502
+ ... result = await external_api.translate(text)
503
+ ...
504
+ ... # Set the cost for this operation
505
+ ... set_trace_cost(char_count * cost_per_char)
506
+ ... return result
507
+ >>>
508
+ >>> # Track compute resource costs
509
+ >>> @trace
510
+ >>> def process_video(video_path: str) -> dict:
511
+ ... duration = get_video_duration(video_path)
512
+ ... cost_per_minute = 0.10 # $0.10 per minute
513
+ ...
514
+ ... result = process_video_content(video_path)
515
+ ...
516
+ ... # Set cost using string format
517
+ ... set_trace_cost(f"${duration * cost_per_minute:.2f}")
518
+ ... return result
519
+ >>>
520
+ >>> # Combine with LLM costs in pipeline
521
+ >>> @pipeline_task
522
+ >>> async def enriched_generation(prompt: str) -> str:
523
+ ... # LLM cost tracked automatically via ModelResponse
524
+ ... response = await llm.generate("gpt-5", messages=prompt)
525
+ ...
526
+ ... # Add cost for post-processing
527
+ ... processing_cost = 0.02 # Fixed cost for enrichment
528
+ ... set_trace_cost(processing_cost)
529
+ ...
530
+ ... return enrich_response(response.content)
531
+
532
+ Raises:
533
+ ValueError: If string format is invalid (not a valid USD amount).
534
+
535
+ Note:
536
+ - This function only works within a traced context (function decorated
537
+ with @trace, @pipeline_task, or @pipeline_flow)
538
+ - LLM costs are tracked automatically via ModelResponse; use this for non-LLM costs
539
+ - Cost should be a positive number representing actual monetary cost in USD
540
+ - The cost is added to the current span's attributes/metadata
541
+ - Multiple calls overwrite the previous cost (not cumulative)
542
+ - If called outside a traced context (no active span), it has no effect
543
+ and does not raise an error
544
+
545
+ See Also:
546
+ - trace: Decorator for adding tracing to functions
547
+ - ModelResponse.get_laminar_metadata: Access LLM generation costs
548
+ - pipeline_task: Task decorator with built-in tracing and optional trace_cost parameter
549
+ - pipeline_flow: Flow decorator with built-in tracing and optional trace_cost parameter
550
+ """
551
+ # Parse string format if provided
552
+ if isinstance(cost, str):
553
+ # Remove dollar sign and any whitespace
554
+ cost_str = cost.strip()
555
+ if not cost_str.startswith("$"):
556
+ raise ValueError(f"Invalid USD format: {cost!r}. Must start with '$' (e.g., '$0.50')")
557
+
558
+ try:
559
+ # Remove $ and convert to float
560
+ cost_value = float(cost_str[1:])
561
+ except ValueError as e:
562
+ raise ValueError(
563
+ f"Invalid USD format: {cost!r}. Must be a valid number after '$'"
564
+ ) from e
565
+ else:
566
+ cost_value = cost
567
+
568
+ if cost_value > 0:
569
+ # Build the attributes dictionary with cost metadata
570
+ attributes: dict[Attributes | str, float] = {
571
+ "gen_ai.usage.output_cost": cost_value,
572
+ "gen_ai.usage.cost": cost_value,
573
+ "cost": cost_value,
574
+ }
575
+
576
+ try:
577
+ Laminar.set_span_attributes(attributes)
578
+ except Exception:
579
+ # Silently ignore if not in a traced context
580
+ pass
581
+
582
+
583
+ __all__ = ["trace", "TraceLevel", "TraceInfo", "set_trace_cost"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ai-pipeline-core
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  Summary: Core utilities for AI-powered processing pipelines using prefect
5
5
  Project-URL: Homepage, https://github.com/bbarwik/ai-pipeline-core
6
6
  Project-URL: Repository, https://github.com/bbarwik/ai-pipeline-core
@@ -57,11 +57,11 @@ AI Pipeline Core is a production-ready framework that combines document processi
57
57
 
58
58
  ### Key Features
59
59
 
60
- - **Document Processing**: Type-safe handling of text, JSON, YAML, PDFs, and images with automatic MIME type detection
61
- - **LLM Integration**: Unified interface to any model via LiteLLM proxy with intelligent context caching
60
+ - **Document Processing**: Type-safe handling of text, JSON, YAML, PDFs, and images with automatic MIME type detection and provenance tracking
61
+ - **LLM Integration**: Unified interface to any model via LiteLLM proxy with configurable context caching
62
62
  - **Structured Output**: Type-safe generation with Pydantic model validation
63
63
  - **Workflow Orchestration**: Prefect-based flows and tasks with automatic retries
64
- - **Observability**: Built-in distributed tracing via Laminar (LMNR) for debugging and monitoring
64
+ - **Observability**: Built-in distributed tracing via Laminar (LMNR) with cost tracking for debugging and monitoring
65
65
  - **Local Development**: Simple runner for testing pipelines without infrastructure
66
66
 
67
67
  ## Installation
@@ -178,6 +178,19 @@ doc = MyDocument.create(
178
178
  # Parse back to original type
179
179
  data = doc.parse(dict) # Returns {"key": "value"}
180
180
 
181
+ # Document provenance tracking (new in v0.1.14)
182
+ doc_with_sources = MyDocument.create(
183
+ name="derived.json",
184
+ content={"result": "processed"},
185
+ sources=[source_doc.sha256, "https://api.example.com/data"]
186
+ )
187
+
188
+ # Check provenance
189
+ for hash in doc_with_sources.get_source_documents():
190
+ print(f"Derived from document: {hash}")
191
+ for ref in doc_with_sources.get_source_references():
192
+ print(f"External source: {ref}")
193
+
181
194
  # Temporary documents (never persisted)
182
195
  temp = TemporaryDocument.create(
183
196
  name="api_response.json",
@@ -211,6 +224,10 @@ if doc.is_text:
211
224
 
212
225
  # Parse structured data
213
226
  data = doc.as_json() # or as_yaml(), as_pydantic_model()
227
+
228
+ # Enhanced filtering (new in v0.1.14)
229
+ filtered = documents.filter_by([Doc1, Doc2, Doc3]) # Multiple types
230
+ named = documents.filter_by(["file1.txt", "file2.txt"]) # Multiple names
214
231
  ```
215
232
 
216
233
  ### LLM Integration
@@ -233,7 +250,7 @@ static_context = AIMessages([large_document])
233
250
  # First call: caches context
234
251
  r1 = await llm.generate(
235
252
  model="gpt-5",
236
- context=static_context, # Cached for 120 seconds
253
+ context=static_context, # Cached for 120 seconds by default
237
254
  messages="Summarize" # Dynamic query
238
255
  )
239
256
 
@@ -243,6 +260,22 @@ r2 = await llm.generate(
243
260
  context=static_context, # Reused from cache!
244
261
  messages="Key points?" # Different query
245
262
  )
263
+
264
+ # Custom cache TTL (new in v0.1.14)
265
+ response = await llm.generate(
266
+ model="gpt-5",
267
+ context=static_context,
268
+ messages="Analyze",
269
+ options=ModelOptions(cache_ttl="300s") # Cache for 5 minutes
270
+ )
271
+
272
+ # Disable caching for dynamic contexts
273
+ response = await llm.generate(
274
+ model="gpt-5",
275
+ context=dynamic_context,
276
+ messages="Process",
277
+ options=ModelOptions(cache_ttl=None) # No caching
278
+ )
246
279
  ```
247
280
 
248
281
  ### Flow Configuration
@@ -272,11 +305,13 @@ class ProcessingConfig(FlowConfig):
272
305
  Enhanced decorators with built-in tracing and monitoring:
273
306
 
274
307
  ```python
275
- from ai_pipeline_core import pipeline_flow, pipeline_task
308
+ from ai_pipeline_core import pipeline_flow, pipeline_task, set_trace_cost
276
309
 
277
310
  @pipeline_task # Automatic retry, tracing, and monitoring
278
311
  async def process_chunk(data: str) -> str:
279
- return await transform(data)
312
+ result = await transform(data)
313
+ set_trace_cost(0.05) # Track costs (new in v0.1.14)
314
+ return result
280
315
 
281
316
  @pipeline_flow # Full observability and orchestration
282
317
  async def main_flow(
@@ -0,0 +1,36 @@
1
+ ai_pipeline_core/__init__.py,sha256=jDITXj2wA7lQ46IT9TOvmjg7Ug2aY_QPkuLYfYQEd2E,5484
2
+ ai_pipeline_core/exceptions.py,sha256=vx-XLTw2fJSPs-vwtXVYtqoQUcOc0JeI7UmHqRqQYWU,1569
3
+ ai_pipeline_core/pipeline.py,sha256=dq-v4IYEaBNt290y545E5JuUahe_k3ffI2_rrGjD-GQ,29384
4
+ ai_pipeline_core/prefect.py,sha256=CC8qeIpVqzNq8m6YWNIcRYeDEqkcAFiNjFwcuwwKO0k,2064
5
+ ai_pipeline_core/prompt_manager.py,sha256=XZwah5fp3GyZ0e0na_yOs6m4ngCcotysh-K_cU2U978,11572
6
+ ai_pipeline_core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ ai_pipeline_core/settings.py,sha256=X8m13zUHWte953l3or45wG8o7ZQ4X-XBe6umk4PlkMQ,4598
8
+ ai_pipeline_core/tracing.py,sha256=uXQdP7GIvTghiqyG3XIgES_DbWfkxU0guSqfiazkc0Q,22877
9
+ ai_pipeline_core/documents/__init__.py,sha256=WHStvGZiSyybOcMTYxSV24U6MA3Am_0_Az5p-DuMFrk,738
10
+ ai_pipeline_core/documents/document.py,sha256=2UfLx4t7k0lV1v2R67mykeEwRAuyAPOCCjvfUOmPDiI,60450
11
+ ai_pipeline_core/documents/document_list.py,sha256=SnWzRqCloI8A6e1HIxaKKbaSkPbL2RrqtkjQKY8H6dI,11354
12
+ ai_pipeline_core/documents/flow_document.py,sha256=GbOa8mjo6xy5t6EUY7E857S0q5nFBgC1yYQdD7gr-Ls,4043
13
+ ai_pipeline_core/documents/mime_type.py,sha256=DkW88K95el5nAmhC00XLS0G3WpDXgs5IRsBWbKiqG3Y,7995
14
+ ai_pipeline_core/documents/task_document.py,sha256=h2jAE3k9-2MJ_MjDrH8UtJRXxNuoxACWBfHu2xEHsN4,4226
15
+ ai_pipeline_core/documents/temporary_document.py,sha256=1Jpi5ozEes4nudilptnXyXatImZDNAhGL7Jd3cQXM3g,2845
16
+ ai_pipeline_core/documents/utils.py,sha256=ZyJNjFN7ihWno0K7dJZed7twYmmPLA0z40UzFw1A3A8,5465
17
+ ai_pipeline_core/flow/__init__.py,sha256=2BfWYMOPYW5teGzwo-qzpn_bom1lxxry0bPsjVgcsCk,188
18
+ ai_pipeline_core/flow/config.py,sha256=4JVc30tztSW9sYufWLN3hx6qSeR1VX31H1aI9I2jIrA,12114
19
+ ai_pipeline_core/flow/options.py,sha256=2rKR2GifhXcyw8avI_oiEDMLC2jm5Qzpw8z56pbxUMo,2285
20
+ ai_pipeline_core/llm/__init__.py,sha256=kLMoOj_JQgvGZXZXU-5u9QzLAu2sq5ixMCyEqk2jKKc,857
21
+ ai_pipeline_core/llm/ai_messages.py,sha256=udzFwUFfQgJeu1JzpqVuBr0QHdWXvuhfJEEgedSHauY,8383
22
+ ai_pipeline_core/llm/client.py,sha256=PZkNaBe1x20ecPTI30PjUjuo26vB76Tam422X3bWhzk,19454
23
+ ai_pipeline_core/llm/model_options.py,sha256=_wAUM3d7b_1oBeSpDjcyyx_wZmvBMobGOyF0JEgLTPg,7660
24
+ ai_pipeline_core/llm/model_response.py,sha256=TUgEi8CLQ1Bw3vvQeNzX3j9YYjuToNZseaMJ7Uaf4GI,15224
25
+ ai_pipeline_core/llm/model_types.py,sha256=JjaJSDY3TTL-ifSLKVNBEV1KJtBIJTr1QwIh9ZnD-is,2895
26
+ ai_pipeline_core/logging/__init__.py,sha256=4iXN4jNiOXLfCYGH3wZB0-Zf-SlU-gQ07f1AyP2H5-s,660
27
+ ai_pipeline_core/logging/logging.yml,sha256=YTW48keO_K5bkkb-KXGM7ZuaYKiquLsjsURei8Ql0V4,1353
28
+ ai_pipeline_core/logging/logging_config.py,sha256=QYI-vz9BqNA02RxoIWPdKhomZpZJkXeFINIuu08O3hY,6242
29
+ ai_pipeline_core/logging/logging_mixin.py,sha256=UFd_CfyJ6YP_XVA-CrpAszOr8g1FH8RwRIwiY23kRG0,8131
30
+ ai_pipeline_core/simple_runner/__init__.py,sha256=OXKFOu3rRcqXCWwBBxnZ7Vz8KRFF5g-G3eJq-vm3CUY,521
31
+ ai_pipeline_core/simple_runner/cli.py,sha256=sbIvv_d401o8h-b5JlcIJQhwzte1sttdmUi2a3As-wY,9357
32
+ ai_pipeline_core/simple_runner/simple_runner.py,sha256=1FC1x0WlOUbOiMbiOtkDQdY0d5NswDbx0FSzrNmewCA,15067
33
+ ai_pipeline_core-0.1.14.dist-info/METADATA,sha256=vzEIlKku7IF-tY0ho30lP8yMaFBWHOASlLa7CaQRsjw,14351
34
+ ai_pipeline_core-0.1.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
+ ai_pipeline_core-0.1.14.dist-info/licenses/LICENSE,sha256=kKj8mfbdWwkyG3U6n7ztB3bAZlEwShTkAsvaY657i3I,1074
36
+ ai_pipeline_core-0.1.14.dist-info/RECORD,,
@@ -1,36 +0,0 @@
1
- ai_pipeline_core/__init__.py,sha256=l2kbSaXDuBJMgFYHDCHKV5u5QxCB8eSTeGz0AL9lMXc,5396
2
- ai_pipeline_core/exceptions.py,sha256=vx-XLTw2fJSPs-vwtXVYtqoQUcOc0JeI7UmHqRqQYWU,1569
3
- ai_pipeline_core/pipeline.py,sha256=EETCEoKkFcVvsQqtVIV5S5DrVII4XPSuCnqF7zA2_jc,28137
4
- ai_pipeline_core/prefect.py,sha256=CC8qeIpVqzNq8m6YWNIcRYeDEqkcAFiNjFwcuwwKO0k,2064
5
- ai_pipeline_core/prompt_manager.py,sha256=XZwah5fp3GyZ0e0na_yOs6m4ngCcotysh-K_cU2U978,11572
6
- ai_pipeline_core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- ai_pipeline_core/settings.py,sha256=X8m13zUHWte953l3or45wG8o7ZQ4X-XBe6umk4PlkMQ,4598
8
- ai_pipeline_core/tracing.py,sha256=ptaJLLWbI6Aq12RYifjChjL5CJByUFFkkF8Vo0u6lu4,18405
9
- ai_pipeline_core/documents/__init__.py,sha256=FOYBUKipW_uuzFieW3MigvNLEpbCI1jeY9_0VxJsoS0,692
10
- ai_pipeline_core/documents/document.py,sha256=tDUBootN_hK75k3XASyBxt-ZqtZuynTwgcL_L5ZWN1Q,51521
11
- ai_pipeline_core/documents/document_list.py,sha256=m8ei2jLTHt47uCKHmn8BuMMbfwPIKH5g9oPO1jvIPmg,8282
12
- ai_pipeline_core/documents/flow_document.py,sha256=bJxLjvUE6xfR5-JCy1oi7XtZOwLBOSuUBBJjRaQk6TI,4748
13
- ai_pipeline_core/documents/mime_type.py,sha256=DkW88K95el5nAmhC00XLS0G3WpDXgs5IRsBWbKiqG3Y,7995
14
- ai_pipeline_core/documents/task_document.py,sha256=HonlS7hO6zisu67JFXu6LjGLyc7BuylUHuP7SMcHCY4,4910
15
- ai_pipeline_core/documents/temporary_document.py,sha256=cMuNLnRlWrMryzfZXOIrTrZ2blsxjmflnL8O3zicWIk,3240
16
- ai_pipeline_core/documents/utils.py,sha256=VHq1gAWTMmJNS55HSZ2--sDErE4DVtFsxrv6y2KXmdk,3472
17
- ai_pipeline_core/flow/__init__.py,sha256=2BfWYMOPYW5teGzwo-qzpn_bom1lxxry0bPsjVgcsCk,188
18
- ai_pipeline_core/flow/config.py,sha256=4JVc30tztSW9sYufWLN3hx6qSeR1VX31H1aI9I2jIrA,12114
19
- ai_pipeline_core/flow/options.py,sha256=UiddkxWrXAhsFtOOt06JhttTp-0gejc8kG0K8Falg1c,2297
20
- ai_pipeline_core/llm/__init__.py,sha256=QWhMVs4OLTgIvOHfxb7AQhpfCXlgGpoGiJ8PSbVyzZs,661
21
- ai_pipeline_core/llm/ai_messages.py,sha256=YS3tfqivj9kS6sYsDAgw9LHEjg9cKS1SAHviCzkvAos,8492
22
- ai_pipeline_core/llm/client.py,sha256=8n1AzDLQMzGjLb-kZ3OTdNa4-648M7GhVJfPPx7sjwU,18194
23
- ai_pipeline_core/llm/model_options.py,sha256=HX3yI9JPCtjR3LIS--Ku9R4YPTfUkqp1kSsMenQejxs,6923
24
- ai_pipeline_core/llm/model_response.py,sha256=IkNXl7AsEPrHIAhsOncpZ52bkOfLp6e3EaXqdf0LtLI,12701
25
- ai_pipeline_core/llm/model_types.py,sha256=Jv2h8oMhIDEBTulWbkmhVS4aiMI39Mzlhk_xOlkCQXo,2829
26
- ai_pipeline_core/logging/__init__.py,sha256=4iXN4jNiOXLfCYGH3wZB0-Zf-SlU-gQ07f1AyP2H5-s,660
27
- ai_pipeline_core/logging/logging.yml,sha256=YTW48keO_K5bkkb-KXGM7ZuaYKiquLsjsURei8Ql0V4,1353
28
- ai_pipeline_core/logging/logging_config.py,sha256=QYI-vz9BqNA02RxoIWPdKhomZpZJkXeFINIuu08O3hY,6242
29
- ai_pipeline_core/logging/logging_mixin.py,sha256=UFd_CfyJ6YP_XVA-CrpAszOr8g1FH8RwRIwiY23kRG0,8131
30
- ai_pipeline_core/simple_runner/__init__.py,sha256=OXKFOu3rRcqXCWwBBxnZ7Vz8KRFF5g-G3eJq-vm3CUY,521
31
- ai_pipeline_core/simple_runner/cli.py,sha256=sbIvv_d401o8h-b5JlcIJQhwzte1sttdmUi2a3As-wY,9357
32
- ai_pipeline_core/simple_runner/simple_runner.py,sha256=Q7PRAgf_VUPS72WV9pER9WT0AQo9r4WbRclsRXXJiW4,14329
33
- ai_pipeline_core-0.1.13.dist-info/METADATA,sha256=20BrzUHIzJ3qYUQy7lx5bl0mBcFtmhzLSkhjS2moAUU,13192
34
- ai_pipeline_core-0.1.13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
- ai_pipeline_core-0.1.13.dist-info/licenses/LICENSE,sha256=kKj8mfbdWwkyG3U6n7ztB3bAZlEwShTkAsvaY657i3I,1074
36
- ai_pipeline_core-0.1.13.dist-info/RECORD,,