Skip to content

Commit 665f15b

Browse files
authored
Merge pull request #268 from Pipelex/release/v0.9.5
### Highlight - Pinned `instructor` to version `<1.10.0` to avoid errors with `mypy` ### Added - Added `PIPELEX_INFERENCE` LLM family enum value - Added support for `PIPELEX_INFERENCE` in OpenAI LLM worker - Added Azure OpenAI platform support for Grok models (`grok-3` and `grok-3-mini`) - Added debug logging for `PipeParallel` output contents - Added `TOML` file filtering in LLM model library loading - Added error handling for Unicode decode errors in LLM model library - Added new test model configurations for `pipelex` and `vertex_ai` platforms ### Changed - Improved error messages in `StuffFactory` to include concept code and stuff name - Disabled `is_gen_object_supported` for all Grok models (`grok-3`, `grok-3-mini`, `grok-3-fast`) - Updated test configurations to use different LLM models and platforms - Modified `Jinja2` filter to use default `TagStyle.TICKS` instead of raising error - Added proper error handling for Unicode decode errors when loading model libraries - Improved error handling in Anthropic plugin tests with specific `AuthenticationError` handling - Image handling in `AnthropicFactory` now converts image URLs to `base64` data URLs with proper MIME type prefix - Put back Discord link in `README.md` ### Fixed - Pinned `instructor` to version `<1.10.0` to avoid errors with `mypy`
2 parents c578766 + 0d3adfb commit 665f15b

15 files changed

Lines changed: 636 additions & 433 deletions

File tree

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
# Changelog
22

3+
## [v0.9.5] - 2025-09-12
4+
5+
### Highlight
6+
- Pinned `instructor` to version `<1.10.0` to avoid errors with `mypy`
7+
8+
### Added
9+
- Added `PIPELEX_INFERENCE` LLM family enum value
10+
- Added support for `PIPELEX_INFERENCE` in OpenAI LLM worker
11+
- Added Azure OpenAI platform support for Grok models (`grok-3` and `grok-3-mini`)
12+
- Added debug logging for `PipeParallel` output contents
13+
- Added `TOML` file filtering in LLM model library loading
14+
- Added error handling for Unicode decode errors in LLM model library
15+
- Added new test model configurations for `pipelex` and `vertex_ai` platforms
16+
17+
### Changed
18+
- Improved error messages in `StuffFactory` to include concept code and stuff name
19+
- Disabled `is_gen_object_supported` for all Grok models (`grok-3`, `grok-3-mini`, `grok-3-fast`)
20+
- Updated test configurations to use different LLM models and platforms
21+
- Modified `Jinja2` filter to use default `TagStyle.TICKS` instead of raising error
22+
- Added proper error handling for Unicode decode errors when loading model libraries
23+
- Improved error handling in Anthropic plugin tests with specific `AuthenticationError` handling
24+
- Image handling in `AnthropicFactory` now converts image URLs to `base64` data URLs with proper MIME type prefix
25+
- Put back Discord link in `README.md`
26+
27+
### Fixed
28+
- Pinned `instructor` to version `<1.10.0` to avoid errors with `mypy`
29+
330
## [v0.9.4] - 2025-09-06
431

532
### Added

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Stop reinventing AI workflows from scratch. With Pipelex, your proven methods be
2222
alt="PyPI – latest release">
2323
<br/>
2424
<br/>
25-
<!-- <a href="https://go.pipelex.com/discord"><img src="https://img.shields.io/badge/Discord-5865F2?logo=discord&logoColor=white" alt="Discord"></a> -->
25+
<a href="https://go.pipelex.com/discord"><img src="https://img.shields.io/badge/Discord-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
2626
<a href="https://www.youtube.com/@PipelexAI"><img src="https://img.shields.io/badge/YouTube-FF0000?logo=youtube&logoColor=white" alt="YouTube"></a>
2727
<a href="https://pipelex.com"><img src="https://img.shields.io/badge/Homepage-03bb95?logo=google-chrome&logoColor=white&style=flat" alt="Website"></a>
2828
<a href="https://github.com/Pipelex/pipelex-cookbook"><img src="https://img.shields.io/badge/Cookbook-5a0dad?logo=github&logoColor=white&style=flat" alt="Cookbook"></a>
@@ -286,11 +286,11 @@ class optimize_tweet_sequence sub_a;
286286

287287
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details on how to get started, including development setup and testing information.
288288

289-
<!-- ## 👥 Join the Community
289+
## 👥 Join the Community
290290

291-
Join our vibrant Discord community to connect with other developers, share your experiences, and get help with your Pipelex projects! -->
291+
Join our vibrant Discord community to connect with other developers, share your experiences, and get help with your Pipelex projects!
292292

293-
<!-- [![Discord](https://img.shields.io/badge/Discord-5865F2?logo=discord&logoColor=white)](https://go.pipelex.com/discord) -->
293+
[![Discord](https://img.shields.io/badge/Discord-5865F2?logo=discord&logoColor=white)](https://go.pipelex.com/discord)
294294

295295
## 💬 Support
296296

pipelex/cogt/llm/llm_models/llm_family.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class LLMFamily(StrEnum):
102102
CUSTOM_QWEN_3 = "custom-qwen3"
103103
CUSTOM_BLACKBOXAI = "custom-blackboxai"
104104

105+
PIPELEX_INFERENCE = "pipelex-inference"
106+
105107
@property
106108
def creator(self) -> LLMCreator:
107109
match self:
@@ -152,7 +154,8 @@ def creator(self) -> LLMCreator:
152154
return LLMCreator.META
153155
case LLMFamily.CUSTOM_QWEN_3:
154156
return LLMCreator.ALIBABA
155-
case LLMFamily.CUSTOM_BLACKBOXAI:
157+
case LLMFamily.CUSTOM_BLACKBOXAI | LLMFamily.PIPELEX_INFERENCE:
158+
# TODO: this doesn't make sense for multi-model providers, needs full refactor
156159
return LLMCreator.OPENAI
157160

158161
@property

pipelex/cogt/llm/llm_models/llm_model_library.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,14 @@ def load_llm_model_library_dict(cls) -> LLMModelLibraryDict:
7373
if not os.path.exists(libraries_path):
7474
raise LLMModelLibraryError(f"LLM model library path `{libraries_path}` not found. Please run `pipelex init-libraries` to create it.")
7575
llm_library: LLMModelLibraryDict = {}
76-
for library_file_name in sorted(os.listdir(libraries_path)):
76+
library_file_names = os.listdir(libraries_path)
77+
library_file_names = [file_name for file_name in library_file_names if file_name.endswith(".toml")]
78+
for library_file_name in sorted(library_file_names):
7779
library_path = os.path.join(libraries_path, library_file_name)
78-
llm_families: LLMModelLibraryDict = load_toml_from_path(library_path)
80+
try:
81+
llm_families: LLMModelLibraryDict = load_toml_from_path(library_path)
82+
except UnicodeDecodeError as exc:
83+
raise LLMModelLibraryError(f"Failed to load LLM model library file '{library_file_name}' from '{library_path}': {exc}")
7984
llm_library.update(llm_families)
8085
return llm_library
8186

pipelex/core/stuffs/stuff_factory.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ def combine_stuffs(
133133
try:
134134
the_stuff_content = the_subclass.model_validate(obj=stuff_contents)
135135
except ValidationError as exc:
136-
raise StuffFactoryError(f"Error combining stuffs: {format_pydantic_validation_error(exc=exc)}") from exc
136+
raise StuffFactoryError(
137+
f"Error combining stuffs for concept {concept.code}, stuff named `{name}`: {format_pydantic_validation_error(exc=exc)}"
138+
) from exc
137139
return cls.make_stuff(
138140
concept=concept,
139141
content=the_stuff_content,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
# OpenAI Models
3+
[pipelex-inference."pipelex/gpt-4o-mini".latest]
4+
is_gen_object_supported = true
5+
is_vision_supported = true
6+
cost_per_million_tokens_usd = { input = 0.15, output = 0.60 }
7+
platform_llm_id = { custom_llm = "pipelex/gpt-4o-mini" }
8+
preferred_platform = "custom_llm"
9+
10+
# Anthropic Models
11+
[pipelex-inference."pipelex/claude-3.7-sonnet".latest]
12+
is_gen_object_supported = true
13+
is_vision_supported = true
14+
cost_per_million_tokens_usd = { input = 0.15, output = 0.60 }
15+
platform_llm_id = { custom_llm = "pipelex/claude-3.7-sonnet" }
16+
preferred_platform = "custom_llm"
17+
18+
# Google Models using VertexAI
19+
[pipelex-inference."pipelex/gemini-2.0-flash-vertex".latest]
20+
is_gen_object_supported = true
21+
is_vision_supported = true
22+
cost_per_million_tokens_usd = { input = 0.15, output = 0.60 }
23+
platform_llm_id = { custom_llm = "pipelex/gemini-2.0-flash-vertex" }
24+
preferred_platform = "custom_llm"
25+
26+
# Google Models using Google API
27+
[pipelex-inference."pipelex/gemini-2.0-flash".latest]
28+
is_gen_object_supported = true
29+
is_vision_supported = true
30+
cost_per_million_tokens_usd = { input = 0.15, output = 0.60 }
31+
platform_llm_id = { custom_llm = "gemini/gemini-2.0-flash" }
32+
preferred_platform = "custom_llm"
33+

pipelex/libraries/llm_integrations/xai.toml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11

22
[grok-3.grok-3.latest]
3-
is_gen_object_supported = true
3+
is_gen_object_supported = false
44
is_vision_supported = false
55
cost_per_million_tokens_usd = { input = 3, output = 15 }
6-
platform_llm_id = { xai = "grok-3-latest" }
6+
platform_llm_id = { xai = "grok-3-latest", azure_openai = "grok-3" }
7+
preferred_platform = "azure_openai"
78

89
[grok-3.grok-3-mini.latest]
9-
is_gen_object_supported = true
10+
is_gen_object_supported = false
1011
is_vision_supported = false
1112
cost_per_million_tokens_usd = { input = 0.3, output = 0.5 }
12-
platform_llm_id = { xai = "grok-3-mini-latest" }
13+
platform_llm_id = { xai = "grok-3-mini-latest", azure_openai = "grok-3-mini" }
14+
preferred_platform = "azure_openai"
1315

1416
[grok-3.grok-3-fast.latest]
15-
is_gen_object_supported = true
17+
is_gen_object_supported = false
1618
is_vision_supported = false
1719
cost_per_million_tokens_usd = { input = 5, output = 25 }
1820
platform_llm_id = { xai = "grok-3-fast-latest" }
1921

20-
2122
[grok-3.grok-3-mini-fast.latest]
22-
is_gen_object_supported = true
23+
is_gen_object_supported = false
2324
is_vision_supported = false
2425
cost_per_million_tokens_usd = { input = 0.15, output = 4 }
2526
platform_llm_id = { xai = "grok-3-mini-fast-latest" }

pipelex/pipe_controllers/parallel/pipe_parallel.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ async def _run_controller_pipe(
189189
f"PipeParallel requires unique output names for each parallel sub pipe, but {sub_pipe_output_name} is already used"
190190
)
191191
output_stuff_contents[sub_pipe_output_name] = output_stuff.content
192+
log.debug(f"PipeParallel '{self.code}': output_stuff_contents[{sub_pipe_output_name}]: {output_stuff_contents[sub_pipe_output_name]}")
192193

193194
if self.combined_output:
194195
combined_output_stuff = StuffFactory.combine_stuffs(

pipelex/plugins/anthropic/anthropic_factory.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
PromptImageTypedBytesOrUrl,
2222
PromptImageUrl,
2323
)
24+
from pipelex.cogt.image.prompt_image_factory import PromptImageFactory
2425
from pipelex.cogt.llm.llm_job import LLMJob
2526
from pipelex.cogt.llm.llm_models.llm_platform import LLMPlatform
2627
from pipelex.cogt.llm.token_category import NbTokensByCategoryDict, TokenCategory
2728
from pipelex.config import get_config
2829
from pipelex.hub import get_plugin_manager, get_secrets_provider
29-
from pipelex.tools.misc.base_64_utils import (
30-
load_binary_as_base64_async,
31-
)
30+
from pipelex.tools.misc.base_64_utils import load_binary_as_base64_async
31+
from pipelex.tools.misc.filetype_utils import detect_file_type_from_base64
3232

3333

3434
class AnthropicFactoryError(CogtError):
@@ -166,7 +166,9 @@ async def _prep_image_for_anthropic(
166166
if isinstance(prompt_image, PromptImageBytes):
167167
typed_bytes_or_url = prompt_image.make_prompt_image_typed_bytes()
168168
elif isinstance(prompt_image, PromptImageUrl):
169-
typed_bytes_or_url = prompt_image.url
169+
image_bytes = await PromptImageFactory().make_promptimagebytes_from_url_async(prompt_image)
170+
file_type = detect_file_type_from_base64(image_bytes.base_64)
171+
typed_bytes_or_url = PromptImageTypedBytes(base_64=image_bytes.base_64, file_type=file_type)
170172
elif isinstance(prompt_image, PromptImagePath):
171173
b64 = await load_binary_as_base64_async(prompt_image.file_path)
172174
typed_bytes_or_url = PromptImageTypedBytes(base_64=b64, file_type=prompt_image.get_file_type())

pipelex/plugins/openai/openai_llm_worker.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ async def _gen_text(
9696
| LLMFamily.PERPLEXITY_REASONING
9797
| LLMFamily.PERPLEXITY_DEEPSEEK
9898
| LLMFamily.GROK_3
99+
| LLMFamily.PIPELEX_INFERENCE
99100
):
100101
response = await self.openai_client_for_text.chat.completions.create(
101102
model=self.llm_engine.llm_id,
@@ -198,6 +199,7 @@ async def _gen_object(
198199
| LLMFamily.PERPLEXITY_REASONING
199200
| LLMFamily.PERPLEXITY_DEEPSEEK
200201
| LLMFamily.GROK_3
202+
| LLMFamily.PIPELEX_INFERENCE
201203
):
202204
result_object, completion = await self.instructor_for_objects.chat.completions.create_with_completion(
203205
model=self.llm_engine.llm_id,

0 commit comments

Comments
 (0)