PlanOpticon

planopticon / video_processor / providers / qianfan_provider.py
Blame History Raw 139 lines
1
"""Baidu Qianfan (ERNIE) provider implementation."""
2
3
import logging
4
import os
5
from pathlib import Path
6
from typing import Optional
7
8
from dotenv import load_dotenv
9
10
from video_processor.providers.base import BaseProvider, ModelInfo, ProviderRegistry
11
12
load_dotenv()
13
logger = logging.getLogger(__name__)
14
15
# Curated list of Qianfan models
16
_QIANFAN_MODELS = [
17
ModelInfo(
18
id="ernie-4.0-8k",
19
provider="qianfan",
20
display_name="ERNIE 4.0 8K",
21
capabilities=["chat"],
22
),
23
ModelInfo(
24
id="ernie-3.5-8k",
25
provider="qianfan",
26
display_name="ERNIE 3.5 8K",
27
capabilities=["chat"],
28
),
29
ModelInfo(
30
id="ernie-speed-8k",
31
provider="qianfan",
32
display_name="ERNIE Speed 8K",
33
capabilities=["chat"],
34
),
35
ModelInfo(
36
id="ernie-lite-8k",
37
provider="qianfan",
38
display_name="ERNIE Lite 8K",
39
capabilities=["chat"],
40
),
41
]
42
43
44
class QianfanProvider(BaseProvider):
45
"""Baidu Qianfan provider using the qianfan SDK."""
46
47
provider_name = "qianfan"
48
49
def __init__(
50
self,
51
access_key: Optional[str] = None,
52
secret_key: Optional[str] = None,
53
):
54
try:
55
import qianfan
56
except ImportError:
57
raise ImportError("qianfan package not installed. Install with: pip install qianfan")
58
59
self._access_key = access_key or os.getenv("QIANFAN_ACCESS_KEY")
60
self._secret_key = secret_key or os.getenv("QIANFAN_SECRET_KEY")
61
62
if not self._access_key or not self._secret_key:
63
raise ValueError("QIANFAN_ACCESS_KEY and QIANFAN_SECRET_KEY must both be set")
64
65
# Set env vars for the SDK to pick up
66
os.environ["QIANFAN_ACCESS_KEY"] = self._access_key
67
os.environ["QIANFAN_SECRET_KEY"] = self._secret_key
68
69
self._qianfan = qianfan
70
self._last_usage = {}
71
72
def chat(
73
self,
74
messages: list[dict],
75
max_tokens: int = 4096,
76
temperature: float = 0.7,
77
model: Optional[str] = None,
78
) -> str:
79
model = model or "ernie-4.0-8k"
80
if model.startswith("qianfan/"):
81
model = model[len("qianfan/") :]
82
83
chat_comp = self._qianfan.ChatCompletion()
84
response = chat_comp.do(
85
model=model,
86
messages=messages,
87
temperature=temperature,
88
max_output_tokens=max_tokens,
89
)
90
91
body = response.get("body", response) if hasattr(response, "get") else response
92
usage = body.get("usage", {}) if hasattr(body, "get") else {}
93
self._last_usage = {
94
"input_tokens": usage.get("prompt_tokens", 0),
95
"output_tokens": usage.get("completion_tokens", 0),
96
}
97
98
result = body.get("result", "") if hasattr(body, "get") else str(body)
99
return result
100
101
def analyze_image(
102
self,
103
image_bytes: bytes,
104
prompt: str,
105
max_tokens: int = 4096,
106
model: Optional[str] = None,
107
) -> str:
108
raise NotImplementedError(
109
"Qianfan image analysis is not supported in this provider. "
110
"Use OpenAI, Anthropic, or Gemini for image analysis."
111
)
112
113
def transcribe_audio(
114
self,
115
audio_path: str | Path,
116
language: Optional[str] = None,
117
model: Optional[str] = None,
118
) -> dict:
119
raise NotImplementedError(
120
"Qianfan does not provide a transcription API through this provider. "
121
"Use OpenAI Whisper or Gemini for transcription."
122
)
123
124
def list_models(self) -> list[ModelInfo]:
125
return list(_QIANFAN_MODELS)
126
127
128
ProviderRegistry.register(
129
name="qianfan",
130
provider_class=QianfanProvider,
131
env_var="QIANFAN_ACCESS_KEY",
132
model_prefixes=["ernie-", "qianfan/"],
133
default_models={
134
"chat": "ernie-4.0-8k",
135
"vision": "",
136
"audio": "",
137
},
138
)
139

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button