dashscope 1.17.1__py3-none-any.whl → 1.18.1__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.

Potentially problematic release.


This version of dashscope might be problematic. Click here for more details.

@@ -24,6 +24,7 @@ class ImageSynthesis(BaseAsyncApi):
24
24
  images: List[str] = None,
25
25
  api_key: str = None,
26
26
  sketch_image_url: str = None,
27
+ ref_img: str = None,
27
28
  workspace: str = None,
28
29
  **kwargs) -> ImageSynthesisResponse:
29
30
  """Call image(s) synthesis service and get result.
@@ -61,6 +62,7 @@ class ImageSynthesis(BaseAsyncApi):
61
62
  images,
62
63
  api_key=api_key,
63
64
  sketch_image_url=sketch_image_url,
65
+ ref_img=ref_img,
64
66
  workspace=workspace,
65
67
  **kwargs)
66
68
 
@@ -72,6 +74,7 @@ class ImageSynthesis(BaseAsyncApi):
72
74
  images: List[str] = None,
73
75
  api_key: str = None,
74
76
  sketch_image_url: str = None,
77
+ ref_img: str = None,
75
78
  workspace: str = None,
76
79
  **kwargs) -> ImageSynthesisResponse:
77
80
  """Create a image(s) synthesis task, and return task information.
@@ -113,6 +116,8 @@ class ImageSynthesis(BaseAsyncApi):
113
116
  input[IMAGES] = images
114
117
  if sketch_image_url is not None and sketch_image_url:
115
118
  input['sketch_image_url'] = sketch_image_url
119
+ if ref_img is not None and ref_img:
120
+ input['ref_img'] == ref_img
116
121
  response = super().async_call(model=model,
117
122
  task_group=task_group,
118
123
  task=ImageSynthesis.task,
@@ -9,6 +9,7 @@ from dashscope.common.constants import (DEFAULT_REQUEST_TIMEOUT_SECONDS,
9
9
  SSE_CONTENT_TYPE, HTTPMethod)
10
10
  from dashscope.common.error import UnsupportedHTTPMethod
11
11
  from dashscope.common.logging import logger
12
+ from dashscope.common.utils import _handle_stream
12
13
 
13
14
 
14
15
  class HttpRequest(BaseRequest):
@@ -83,34 +84,14 @@ class HttpRequest(BaseRequest):
83
84
  pass
84
85
  return output
85
86
 
86
- def _handle_stream(self, response: requests.Response):
87
- # TODO define done message.
88
- is_error = False
89
- status_code = HTTPStatus.INTERNAL_SERVER_ERROR
90
- for line in response.iter_lines():
91
- if line:
92
- line = line.decode('utf8')
93
- line = line.rstrip('\n').rstrip('\r')
94
- if line.startswith('event:error'):
95
- is_error = True
96
- elif line.startswith('status:'):
97
- status_code = line[len('status:'):]
98
- status_code = int(status_code.strip())
99
- elif line.startswith('data:'):
100
- line = line[len('data:'):]
101
- yield (is_error, status_code, line)
102
- if is_error:
103
- break
104
- else:
105
- continue # ignore heartbeat...
106
-
107
87
  def _handle_response(self, response: requests.Response):
108
88
  request_id = ''
109
89
  if (response.status_code == HTTPStatus.OK and self.stream
110
90
  and SSE_CONTENT_TYPE in response.headers.get(
111
91
  'content-type', '')):
112
- for is_error, status_code, data in self._handle_stream(response):
92
+ for is_error, status_code, event in _handle_stream(response):
113
93
  try:
94
+ data = event.data
114
95
  output = None
115
96
  usage = None
116
97
  msg = json.loads(data)
@@ -15,8 +15,9 @@ from dashscope.common.constants import (DEFAULT_REQUEST_TIMEOUT_SECONDS,
15
15
  from dashscope.common.error import InvalidParameter, InvalidTask, ModelRequired
16
16
  from dashscope.common.logging import logger
17
17
  from dashscope.common.utils import (_handle_http_failed_response,
18
- _handle_http_response, default_headers,
19
- join_url)
18
+ _handle_http_response,
19
+ _handle_http_stream_response,
20
+ default_headers, join_url)
20
21
 
21
22
 
22
23
  class BaseAioApi():
@@ -720,6 +721,7 @@ class CreateMixin():
720
721
  data: object,
721
722
  api_key: str = None,
722
723
  path: str = None,
724
+ stream: bool = False,
723
725
  workspace: str = None,
724
726
  **kwargs) -> Union[DashScopeAPIResponse, Dict]:
725
727
  """Create a object
@@ -741,6 +743,7 @@ class CreateMixin():
741
743
  logger.debug('Starting request: %s' % url)
742
744
  response = session.post(url,
743
745
  json=data,
746
+ stream=stream,
744
747
  headers={
745
748
  **_workspace_header(workspace),
746
749
  **default_headers(api_key),
@@ -748,7 +751,16 @@ class CreateMixin():
748
751
  },
749
752
  timeout=timeout)
750
753
  logger.debug('Starting processing response: %s' % url)
751
- return _handle_http_response(response, flattened_output)
754
+ response = _handle_http_stream_response(response, flattened_output)
755
+ if stream:
756
+ return (item for item in response)
757
+ else:
758
+ _, output = next(response)
759
+ try:
760
+ next(response)
761
+ except StopIteration:
762
+ pass
763
+ return output
752
764
 
753
765
 
754
766
  class UpdateMixin():
dashscope/common/error.py CHANGED
@@ -58,6 +58,27 @@ class UnsupportedData(DashScopeException):
58
58
  pass
59
59
 
60
60
 
61
+ class AssistantError(DashScopeException):
62
+ def __init__(self, **kwargs):
63
+ self.message = None
64
+ self.code = None
65
+ self.request_id = None
66
+ if 'message' in kwargs:
67
+ import json
68
+ msg = json.loads(kwargs['message'])
69
+ if 'request_id' in msg:
70
+ self.request_id = msg['request_id']
71
+ if 'code' in msg:
72
+ self.code = msg['code']
73
+ if 'message' in msg:
74
+ self.message = msg['message']
75
+
76
+ def __str__(self):
77
+ msg = 'Request failed, request_id: %s, code: %s, message: %s' % ( # noqa E501
78
+ self.request_id, self.code, self.message)
79
+ return msg
80
+
81
+
61
82
  # for server send generation or inference error.
62
83
  class RequestFailure(DashScopeException):
63
84
  def __init__(self,
dashscope/common/utils.py CHANGED
@@ -2,6 +2,7 @@ import asyncio
2
2
  import json
3
3
  import os
4
4
  import platform
5
+ from dataclasses import dataclass
5
6
  from http import HTTPStatus
6
7
  from typing import Dict
7
8
  from urllib.parse import urlparse
@@ -11,6 +12,8 @@ import requests
11
12
 
12
13
  from dashscope.api_entities.dashscope_response import DashScopeAPIResponse
13
14
  from dashscope.common.api_key import get_default_api_key
15
+ from dashscope.common.constants import SSE_CONTENT_TYPE
16
+ from dashscope.common.logging import logger
14
17
  from dashscope.version import __version__
15
18
 
16
19
 
@@ -163,6 +166,51 @@ async def _handle_aiohttp_response(response: aiohttp.ClientResponse):
163
166
  message=msg)
164
167
 
165
168
 
169
+ @dataclass
170
+ class SSEEvent:
171
+ id: str
172
+ eventType: str
173
+ data: str
174
+
175
+ def __init__(self, id: str, type: str, data: str):
176
+ self.id = id
177
+ self.eventType = type
178
+ self.data = data
179
+
180
+
181
+ def _handle_stream(response: requests.Response):
182
+ # TODO define done message.
183
+ is_error = False
184
+ status_code = HTTPStatus.INTERNAL_SERVER_ERROR
185
+ event = SSEEvent(None, None, None)
186
+ eventType = None
187
+ for line in response.iter_lines():
188
+ if line:
189
+ line = line.decode('utf8')
190
+ line = line.rstrip('\n').rstrip('\r')
191
+ if line.startswith('id:'):
192
+ id = line[len('id:'):]
193
+ event.id = id.strip()
194
+ elif line.startswith('event:'):
195
+ eventType = line[len('event:'):]
196
+ event.eventType = eventType.strip()
197
+ if eventType == 'error':
198
+ is_error = True
199
+ elif line.startswith('status:'):
200
+ status_code = line[len('status:'):]
201
+ status_code = int(status_code.strip())
202
+ elif line.startswith('data:'):
203
+ line = line[len('data:'):]
204
+ event.data = line.strip()
205
+ if eventType is not None and eventType == 'done':
206
+ continue
207
+ yield (is_error, status_code, event)
208
+ if is_error:
209
+ break
210
+ else:
211
+ continue # ignore heartbeat...
212
+
213
+
166
214
  def _handle_http_failed_response(
167
215
  response: requests.Response,
168
216
  flattened_output: bool = False) -> DashScopeAPIResponse:
@@ -198,38 +246,105 @@ def _handle_http_failed_response(
198
246
 
199
247
  def _handle_http_response(response: requests.Response,
200
248
  flattened_output: bool = False):
249
+ response = _handle_http_stream_response(response, flattened_output)
250
+ _, output = next(response)
251
+ try:
252
+ next(response)
253
+ except StopIteration:
254
+ pass
255
+ return output
256
+
257
+
258
+ def _handle_http_stream_response(response: requests.Response,
259
+ flattened_output: bool = False):
201
260
  request_id = ''
202
- if response.status_code == HTTPStatus.OK or response.status_code == HTTPStatus.CREATED:
261
+ if (response.status_code == HTTPStatus.OK
262
+ and SSE_CONTENT_TYPE in response.headers.get('content-type', '')):
263
+ for is_error, status_code, event in _handle_stream(response):
264
+ if not is_error:
265
+ try:
266
+ output = None
267
+ usage = None
268
+ msg = json.loads(event.data)
269
+ if flattened_output:
270
+ msg['status_code'] = response.status_code
271
+ yield event.eventType, msg
272
+ else:
273
+ logger.debug('Stream message: %s' % msg)
274
+ if not is_error:
275
+ if 'output' in msg:
276
+ output = msg['output']
277
+ if 'usage' in msg:
278
+ usage = msg['usage']
279
+ if 'request_id' in msg:
280
+ request_id = msg['request_id']
281
+ yield event.eventType, DashScopeAPIResponse(
282
+ request_id=request_id,
283
+ status_code=HTTPStatus.OK,
284
+ output=output,
285
+ usage=usage)
286
+ except json.JSONDecodeError as e:
287
+ if flattened_output:
288
+ yield event.eventType, {
289
+ 'status_code': response.status_code,
290
+ 'message': e.message
291
+ }
292
+ else:
293
+ yield event.eventType, DashScopeAPIResponse(
294
+ request_id=request_id,
295
+ status_code=HTTPStatus.BAD_REQUEST,
296
+ output=None,
297
+ code='Unknown',
298
+ message=event.data)
299
+ continue
300
+ else:
301
+ if flattened_output:
302
+ yield event.eventType, {
303
+ 'status_code': status_code,
304
+ 'message': event.data
305
+ }
306
+ else:
307
+ msg = json.loads(event.eventType)
308
+ yield event.eventType, DashScopeAPIResponse(
309
+ request_id=request_id,
310
+ status_code=status_code,
311
+ output=None,
312
+ code=msg['code']
313
+ if 'code' in msg else None, # noqa E501
314
+ message=msg['message']
315
+ if 'message' in msg else None) # noqa E501
316
+ elif response.status_code == HTTPStatus.OK or response.status_code == HTTPStatus.CREATED:
203
317
  json_content = response.json()
204
318
  if flattened_output:
205
319
  json_content['status_code'] = response.status_code
206
- return json_content
207
- output = None
208
- usage = None
209
- code = None
210
- msg = ''
211
- if 'data' in json_content:
212
- output = json_content['data']
213
- if 'code' in json_content:
214
- code = json_content['code']
215
- if 'message' in json_content:
216
- msg = json_content['message']
217
- if 'output' in json_content:
218
- output = json_content['output']
219
- if 'usage' in json_content:
220
- usage = json_content['usage']
221
- if 'request_id' in json_content:
222
- request_id = json_content['request_id']
223
- json_content.pop('request_id', None)
224
-
225
- if 'data' not in json_content and 'output' not in json_content:
226
- output = json_content
227
-
228
- return DashScopeAPIResponse(request_id=request_id,
229
- status_code=response.status_code,
230
- code=code,
231
- output=output,
232
- usage=usage,
233
- message=msg)
320
+ yield None, json_content
321
+ else:
322
+ output = None
323
+ usage = None
324
+ code = None
325
+ msg = ''
326
+ if 'data' in json_content:
327
+ output = json_content['data']
328
+ if 'code' in json_content:
329
+ code = json_content['code']
330
+ if 'message' in json_content:
331
+ msg = json_content['message']
332
+ if 'output' in json_content:
333
+ output = json_content['output']
334
+ if 'usage' in json_content:
335
+ usage = json_content['usage']
336
+ if 'request_id' in json_content:
337
+ request_id = json_content['request_id']
338
+ json_content.pop('request_id', None)
339
+
340
+ if 'data' not in json_content and 'output' not in json_content:
341
+ output = json_content
342
+
343
+ yield None, DashScopeAPIResponse(request_id=request_id,
344
+ status_code=response.status_code,
345
+ code=code,
346
+ output=output,
347
+ usage=usage,
348
+ message=msg)
234
349
  else:
235
- return _handle_http_failed_response(response, flattened_output)
350
+ yield None, _handle_http_failed_response(response, flattened_output)
@@ -5,9 +5,12 @@ from typing import Dict, List, Optional
5
5
  from dashscope.client.base_api import (CancelMixin, CreateMixin,
6
6
  GetStatusMixin, ListObjectMixin,
7
7
  UpdateMixin)
8
- from dashscope.common.error import InputRequired, TimeoutException
8
+ from dashscope.common.error import (AssistantError, InputRequired,
9
+ TimeoutException)
9
10
  from dashscope.common.logging import logger
10
- from dashscope.threads.thread_types import Run, RunList
11
+ from dashscope.threads.thread_types import (Run, RunList, RunStep,
12
+ RunStepDelta, Thread,
13
+ ThreadMessage, ThreadMessageDelta)
11
14
 
12
15
  __all__ = ['Runs']
13
16
 
@@ -25,8 +28,10 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
25
28
  instructions: Optional[str] = None,
26
29
  additional_instructions: Optional[str] = None,
27
30
  tools: Optional[List[Dict]] = None,
31
+ stream: Optional[bool] = False,
28
32
  metadata: Optional[Dict] = None,
29
33
  workspace: str = None,
34
+ extra_body: Optional[Dict] = None,
30
35
  api_key: str = None,
31
36
  **kwargs) -> Run:
32
37
  if not assistant_id:
@@ -44,14 +49,22 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
44
49
  data['tools'] = tools
45
50
  if metadata:
46
51
  data['metadata'] = metadata
52
+ data['stream'] = stream
53
+ if extra_body is not None and extra_body:
54
+ data = {**data, **extra_body}
47
55
 
48
56
  response = super().call(data=data,
49
57
  path='threads/runs',
50
58
  api_key=api_key,
51
59
  flattened_output=True,
60
+ stream=stream,
52
61
  workspace=workspace,
53
62
  **kwargs)
54
- return Run(**response)
63
+ if stream:
64
+ return ((event_type, cls.convert_stream_object(event_type, item))
65
+ for event_type, item in response)
66
+ else:
67
+ return Run(**response)
55
68
 
56
69
  @classmethod
57
70
  def create(cls,
@@ -63,7 +76,9 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
63
76
  additional_instructions: Optional[str] = None,
64
77
  tools: Optional[List[Dict]] = None,
65
78
  metadata: Optional[Dict] = None,
79
+ stream: Optional[bool] = False,
66
80
  workspace: str = None,
81
+ extra_body: Optional[Dict] = None,
67
82
  api_key: str = None,
68
83
  **kwargs) -> Run:
69
84
  """Create a run.
@@ -101,14 +116,53 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
101
116
  data['tools'] = tools
102
117
  if metadata:
103
118
  data['metadata'] = metadata
119
+ data['stream'] = stream
120
+ if extra_body is not None and extra_body:
121
+ data = {**data, **extra_body}
104
122
 
105
123
  response = super().call(data=data,
106
124
  path=f'threads/{thread_id}/runs',
107
125
  api_key=api_key,
108
126
  flattened_output=True,
127
+ stream=stream,
109
128
  workspace=workspace,
110
129
  **kwargs)
111
- return Run(**response)
130
+ if stream:
131
+ return ((event_type, cls.convert_stream_object(event_type, item))
132
+ for event_type, item in response)
133
+ else:
134
+ return Run(**response)
135
+
136
+ @classmethod
137
+ def convert_stream_object(cls, event, item):
138
+ event_object_map = {
139
+ 'thread.created': Thread,
140
+ 'thread.run.created': Run,
141
+ 'thread.run.queued': Run,
142
+ 'thread.run.in_progress': Run,
143
+ 'thread.run.requires_action': Run,
144
+ 'thread.run.completed': Run,
145
+ 'thread.run.failed': Run,
146
+ 'thread.run.cancelled': Run,
147
+ 'thread.run.expired': Run,
148
+ 'thread.run.step.created': RunStep,
149
+ 'thread.run.step.in_progress': RunStep,
150
+ 'thread.run.step.delta': RunStepDelta,
151
+ 'thread.run.step.completed': RunStep,
152
+ 'thread.run.step.failed': RunStep,
153
+ 'thread.run.step.cancelled': RunStep,
154
+ 'thread.run.step.expired': RunStep,
155
+ 'thread.message.created': ThreadMessage,
156
+ 'thread.message.in_progress': ThreadMessage,
157
+ 'thread.message.delta': ThreadMessageDelta,
158
+ 'thread.message.completed': ThreadMessage,
159
+ 'thread.message.incomplete': ThreadMessage,
160
+ 'error': AssistantError,
161
+ }
162
+ if (event in event_object_map):
163
+ return event_object_map[event](**item)
164
+ else:
165
+ return item
112
166
 
113
167
  @classmethod
114
168
  def call(cls,
@@ -119,8 +173,10 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
119
173
  instructions: Optional[str] = None,
120
174
  additional_instructions: Optional[str] = None,
121
175
  tools: Optional[List[Dict]] = None,
176
+ stream: Optional[bool] = False,
122
177
  metadata: Optional[Dict] = None,
123
178
  workspace: str = None,
179
+ extra_body: Optional[Dict] = None,
124
180
  api_key: str = None,
125
181
  **kwargs) -> Run:
126
182
  """Create a run.
@@ -151,8 +207,10 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
151
207
  instructions=instructions,
152
208
  additional_instructions=additional_instructions,
153
209
  tools=tools,
210
+ stream=stream,
154
211
  metadata=metadata,
155
212
  workspace=workspace,
213
+ extra_body=extra_body,
156
214
  api_key=api_key,
157
215
  **kwargs)
158
216
 
@@ -254,7 +312,9 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
254
312
  *,
255
313
  thread_id: str,
256
314
  tool_outputs: List[Dict],
315
+ stream: Optional[bool] = False,
257
316
  workspace: str = None,
317
+ extra_body: Optional[Dict] = None,
258
318
  api_key: str = None,
259
319
  **kwargs) -> Run:
260
320
  """_summary_
@@ -278,14 +338,24 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
278
338
  if not thread_id or not run_id:
279
339
  raise InputRequired('thread_id and run_id are required!')
280
340
 
341
+ data = {'tool_outputs': tool_outputs}
342
+ data['stream'] = stream
343
+ if extra_body is not None and extra_body:
344
+ data = {**data, **extra_body}
345
+
281
346
  response = super().call(
282
- {'tool_outputs': tool_outputs},
347
+ data,
283
348
  path=f'threads/{thread_id}/runs/{run_id}/submit_tool_outputs',
284
349
  workspace=workspace,
285
350
  api_key=api_key,
351
+ stream=stream,
286
352
  flattened_output=True,
287
353
  **kwargs)
288
- return Run(**response)
354
+ if stream:
355
+ return ((event_type, cls.convert_stream_object(event_type, item))
356
+ for event_type, item in response)
357
+ else:
358
+ return Run(**response)
289
359
 
290
360
  @classmethod
291
361
  def wait(cls,
@@ -316,6 +386,12 @@ class Runs(CreateMixin, CancelMixin, ListObjectMixin, GetStatusMixin,
316
386
  thread_id=thread_id,
317
387
  workspace=workspace,
318
388
  api_key=api_key)
389
+ import json
390
+ print(
391
+ json.dumps(run,
392
+ default=lambda o: o.__dict__,
393
+ sort_keys=True,
394
+ indent=4))
319
395
  if run.status_code == HTTPStatus.OK:
320
396
  if hasattr(run, 'status'):
321
397
  if run.status in [
@@ -85,6 +85,8 @@ class Text(BaseObjectMixin):
85
85
  self.annotations = []
86
86
  for annotation in annotations:
87
87
  self.annotations.append(annotation)
88
+ else:
89
+ self.annotations = annotations
88
90
  super().__init__(**kwargs)
89
91
 
90
92
 
@@ -108,6 +110,42 @@ MESSAGE_SUPPORT_CONTENT = {
108
110
  Content = Union[MessageContentImageFile, MessageContentText]
109
111
 
110
112
 
113
+ @dataclass(init=False)
114
+ class ThreadMessageDeltaContent(BaseObjectMixin):
115
+ content: Content
116
+ role: str
117
+
118
+ def __init__(self, **kwargs):
119
+ contents = kwargs.pop('content', None)
120
+ if contents:
121
+ for item in contents:
122
+ if item['type'] == 'text':
123
+ self.content = MessageContentText(**item)
124
+ elif item['type'] == 'image_file':
125
+ self.content = MessageContentImageFile(**item)
126
+ else:
127
+ self.content = item
128
+ else:
129
+ self.content = contents
130
+ super().__init__(**kwargs)
131
+
132
+
133
+ @dataclass(init=False)
134
+ class ThreadMessageDelta(BaseObjectMixin):
135
+ status_code: int
136
+ id: str
137
+ object: str = 'thread.message.delta'
138
+ delta: ThreadMessageDeltaContent
139
+
140
+ def __init__(self, **kwargs):
141
+ content = kwargs.pop('delta', None)
142
+ if content:
143
+ self.delta = ThreadMessageDeltaContent(**content)
144
+ else:
145
+ self.delta = None
146
+ super().__init__(**kwargs)
147
+
148
+
111
149
  @dataclass(init=False)
112
150
  class ThreadMessage(BaseObjectMixin):
113
151
  status_code: int
@@ -137,6 +175,8 @@ class ThreadMessage(BaseObjectMixin):
137
175
  else:
138
176
  content_list.append(content)
139
177
  self.content = content_list
178
+ else:
179
+ self.content = input_content
140
180
 
141
181
  super().__init__(**kwargs)
142
182
 
@@ -203,6 +243,8 @@ class RequiredActionSubmitToolOutputs(BaseObjectMixin):
203
243
  self.tool_calls = []
204
244
  for tc in tcs:
205
245
  self.tool_calls.append(RequiredActionFunctionToolCall(**tc))
246
+ else:
247
+ self.tool_calls = tcs
206
248
  super().__init__(**kwargs)
207
249
 
208
250
 
@@ -265,6 +307,8 @@ class Run(BaseObjectMixin):
265
307
  actions = kwargs.pop('required_action', None)
266
308
  if actions:
267
309
  self.required_action = RequiredAction(**actions)
310
+ else:
311
+ self.required_action = actions
268
312
 
269
313
  super().__init__(**kwargs)
270
314
 
@@ -387,10 +431,10 @@ class RetrievalToolCall(BaseObjectMixin):
387
431
  retrieval: object
388
432
  """For now, this is always going to be an empty object."""
389
433
 
390
- type: Literal['retrieval']
434
+ type: Literal['quark_search']
391
435
  """The type of tool call.
392
436
 
393
- This is always going to be `retrieval` for this type of tool call.
437
+ This is always going to be `quark_search` for this type of tool call.
394
438
  """
395
439
  def __init__(self, **kwargs):
396
440
  super().__init__(**kwargs)
@@ -469,9 +513,34 @@ def convert_step_details_dict_to_objects(step_details):
469
513
  return step_details
470
514
 
471
515
 
516
+ @dataclass(init=False)
517
+ class RunStepDeltaContent(BaseObjectMixin):
518
+ step_details: StepDetails
519
+
520
+ def __init__(self, **kwargs):
521
+ self.step_details = convert_step_details_dict_to_objects(
522
+ kwargs.pop('step_details', {}))
523
+ super().__init__(**kwargs)
524
+
525
+
526
+ @dataclass(init=False)
527
+ class RunStepDelta(BaseObjectMixin):
528
+ id: str
529
+ object: str = 'thread.run.step.delta'
530
+ delta: RunStepDeltaContent
531
+
532
+ def __init__(self, **kwargs):
533
+ delta = kwargs.pop('delta', None)
534
+ if delta:
535
+ self.delta = RunStepDeltaContent(**delta)
536
+ else:
537
+ self.delta = delta
538
+ super().__init__(**kwargs)
539
+
540
+
472
541
  @dataclass(init=False)
473
542
  class RunStep(BaseObjectMixin):
474
- status_code: int
543
+ status_code: int = None
475
544
  id: str
476
545
  """The identifier of the run step, which can be referenced in API endpoints."""
477
546
 
@@ -547,10 +616,15 @@ class RunStep(BaseObjectMixin):
547
616
  def __init__(self, **kwargs):
548
617
  self.step_details = convert_step_details_dict_to_objects(
549
618
  kwargs.pop('step_details', {}))
550
- self.usage = Usage(**kwargs.pop('usage', {}))
619
+ if 'usage' in kwargs and kwargs['usage'] is not None and kwargs['usage']:
620
+ self.usage = Usage(**kwargs.pop('usage', {}))
621
+ else:
622
+ self.usage = None
551
623
  last_error = kwargs.pop('last_error', None)
552
624
  if last_error:
553
625
  self.last_error = LastError(**last_error)
626
+ else:
627
+ last_error = last_error
554
628
  super().__init__(**kwargs)
555
629
 
556
630
 
@@ -564,8 +638,14 @@ class RunStepList(BaseList):
564
638
  first_id: Optional[str] = None,
565
639
  data: List[RunStep] = [],
566
640
  **kwargs):
641
+ if data:
642
+ steps = []
643
+ for step in data:
644
+ steps.append(RunStep(**step))
645
+ self.data = steps
646
+ else:
647
+ self.data = []
567
648
  super().__init__(has_more=has_more,
568
649
  last_id=last_id,
569
650
  first_id=first_id,
570
- data=data,
571
651
  **kwargs)
dashscope/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.17.1'
1
+ __version__ = '1.18.1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dashscope
3
- Version: 1.17.1
3
+ Version: 1.18.1
4
4
  Summary: dashscope client sdk library
5
5
  Home-page: https://dashscope.aliyun.com/
6
6
  Author: Alibaba Cloud
@@ -6,12 +6,12 @@ dashscope/files.py,sha256=QgJjwhtn9F548nCA8jD8OvE6aQEj-20hZqJgYXsUdQU,3930
6
6
  dashscope/finetune.py,sha256=_tflDUvu0KagSoCzLaf0hofpG_P8NU6PylL8CPjVhrA,6243
7
7
  dashscope/model.py,sha256=UPOn1qMYFhX-ovXi3BMxZEBk8qOK7WLJOYHMbPZwYBo,1440
8
8
  dashscope/models.py,sha256=UPOn1qMYFhX-ovXi3BMxZEBk8qOK7WLJOYHMbPZwYBo,1440
9
- dashscope/version.py,sha256=89nBqIh38Ngg_NbAy6gQPiec_0UERVsBY2sbVqreGgA,23
9
+ dashscope/version.py,sha256=I5ZqRqhAJhmCPjHV4Y-aZSwFiizEYHBBRN0cXvrD1-A,23
10
10
  dashscope/aigc/__init__.py,sha256=s-MCA87KYiVumYtKtJi5IMN7xelSF6TqEU3s3_7RF-Y,327
11
11
  dashscope/aigc/code_generation.py,sha256=KAJVrGp6tiNFBBg64Ovs9RfcP5SrIhrbW3wdA89NKso,10885
12
12
  dashscope/aigc/conversation.py,sha256=xRoJlCR-IXHjSdkDrK74a9ut1FJg0FZhTNXZAJC18MA,14231
13
13
  dashscope/aigc/generation.py,sha256=9PMAhSy5Ht5eizUGXnDdk8Jl3yIDM4fR8eSxn1W4c-U,10051
14
- dashscope/aigc/image_synthesis.py,sha256=b7813Yz9Ivv2KijXfBSycRE1rer4uVRS2Ntx_lPts1A,9791
14
+ dashscope/aigc/image_synthesis.py,sha256=7A5txSkKBkg5pN5F7IP5C90277Yk8fkKAWu30YhskdM,9994
15
15
  dashscope/aigc/multimodal_conversation.py,sha256=SlNnnsUPV19gdx8fYJAtsMFWPNGY6vhk5IGHZ5ZczpI,5369
16
16
  dashscope/api_entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  dashscope/api_entities/aiohttp_request.py,sha256=aE3AeWba8Ig_xHMYjrAdkq0N61l_L2VFTG6HYh912X0,10229
@@ -19,7 +19,7 @@ dashscope/api_entities/api_request_data.py,sha256=JUMcfpJjKXEZLCBSFIDpgoaeQYk5uK
19
19
  dashscope/api_entities/api_request_factory.py,sha256=4p-qxMuvCA0CmUHdH19QaUCaHmlLHAM1X2Jd4YKt5c0,4661
20
20
  dashscope/api_entities/base_request.py,sha256=cXUL7xqSV8wBr5d-1kx65AO3IsRR9A_ps6Lok-v-MKM,926
21
21
  dashscope/api_entities/dashscope_response.py,sha256=Bp1T7HwVlkOvpMNg-AEjz-BScxhLUXMXlE8ApXTtfhQ,17872
22
- dashscope/api_entities/http_request.py,sha256=Y25LeW3Sq73AbjP-Zsvs1CYMsSBPEBTFXcthbFkV0dI,9834
22
+ dashscope/api_entities/http_request.py,sha256=Y9z4PcRAPlp6Ozfz9P3IVP3y9cufhhIFjXaJOF6xCtQ,9043
23
23
  dashscope/api_entities/websocket_request.py,sha256=IaydqRvOSr5IdSSpnX8Vc8rRoVldjfcrLvDxTnPep9g,14676
24
24
  dashscope/app/__init__.py,sha256=OOV2rFy0QlA9Gu3XVPtWJoBwK1J11BdGhkEdX_sdYGU,68
25
25
  dashscope/app/application.py,sha256=AegGVsk3dDzYACoYRNNjo3eG-2wrDd0dlOjYHpF0r2Y,7949
@@ -36,16 +36,16 @@ dashscope/audio/asr/transcription.py,sha256=e5O1U51GT-OQPu-wWN2w_T7l6IopWuGMVkhe
36
36
  dashscope/audio/tts/__init__.py,sha256=fbnieZX9yNFNh5BsxLpLXb63jlxzxrdCJakV3ignjlQ,194
37
37
  dashscope/audio/tts/speech_synthesizer.py,sha256=dnKx9FDDdO_ETHAjhK8zaMVaH6SfoTtN5YxXXqgY1JA,7571
38
38
  dashscope/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- dashscope/client/base_api.py,sha256=k6DS7dtVGTeavAzKOl_DDruyRN8UzvjAtjhSRbXgiNQ,40587
39
+ dashscope/client/base_api.py,sha256=UDxvwlxiR0KZwj_AI0jACfkLErJ55voure82OmOiDMk,41034
40
40
  dashscope/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  dashscope/common/api_key.py,sha256=5Stp0odL5JSuIO3qJBp23QNppuGbqhhvKPS66qbMs0I,1986
42
42
  dashscope/common/base_type.py,sha256=wKqLGrr2o9bpI43ws1P0YCuJmoS17J9_Rw_uuYHjIFQ,4531
43
43
  dashscope/common/constants.py,sha256=86Zc45f1-OEgNdLTu-4_Pl0U3wRyi5qFt4E7dLlaglU,2327
44
44
  dashscope/common/env.py,sha256=oQOZW5JyEeTSde394un2lpDJ5RBh4fMU9hBfbtrKKkc,869
45
- dashscope/common/error.py,sha256=eFUSBNERfXYQ4g3bVka_IGuRG1A06Zf6njObBtR2z6E,1951
45
+ dashscope/common/error.py,sha256=Q7GRhniP-7ap4HBpU69frRdKgKLwmH4ySYxCtupsr60,2638
46
46
  dashscope/common/logging.py,sha256=ecGxylG3bWES_Xv5-BD6ep4_0Ciu7F6ZPBjiZtu9Jx4,984
47
47
  dashscope/common/message_manager.py,sha256=i5149WzDk6nWmdFaHzYx4USXMBeX18GKSI-F4fLwbN0,1097
48
- dashscope/common/utils.py,sha256=oGwoDgO31-Filg64GrhyR14lxORhE3esVPJvnOgtpvw,7365
48
+ dashscope/common/utils.py,sha256=5jg7q5NE0LE1NigbpfrOkqXjPYqb-3jfFOh7g-nWB1Q,12017
49
49
  dashscope/embeddings/__init__.py,sha256=-dxHaoxZZVuP-wAGUIa3sNNh8CQwaeWj2UlqsDy1sV4,240
50
50
  dashscope/embeddings/batch_text_embedding.py,sha256=P32LFO9v7ehdJsl0c32In94hUET6K6AaGJ_pDRtFqco,8791
51
51
  dashscope/embeddings/batch_text_embedding_response.py,sha256=WziXlQsFIkL1kPc_7lRG1HtqgkO5vVThtnNqExJggNU,2000
@@ -61,13 +61,13 @@ dashscope/rerank/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
61
61
  dashscope/rerank/text_rerank.py,sha256=1L-RLUxMCvNhbMud1FUG6YFWT7ZV979fzhMEuVjJ1oI,2398
62
62
  dashscope/resources/qwen.tiktoken,sha256=srG437XMXwJLr8NzEhxquj9m-aWgJp4kNHCh3hajMYY,2561218
63
63
  dashscope/threads/__init__.py,sha256=md5bsHekHHGOg3uQrBCk8f4BCNnA1AuI_-LDf92pNVU,621
64
- dashscope/threads/thread_types.py,sha256=h1fYspH_ppCv32ffjTXIiGKBSgzEVtOdwT57xlcEd_Q,16028
64
+ dashscope/threads/thread_types.py,sha256=SwAJNi-RbqFXlrztDUCt0q0MfgfJLHyYl9qWrQDmQQo,18280
65
65
  dashscope/threads/threads.py,sha256=dD72xklN71KFGBVoBVHEbCbZADwLbi9yGS9LbFpnlAI,7665
66
66
  dashscope/threads/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
67
  dashscope/threads/messages/files.py,sha256=wi0nJ2zsPWOw2Jn-ZkxA3URZBIrkGxqM_uAPfXY1xv0,3820
68
68
  dashscope/threads/messages/messages.py,sha256=Zjmyf3rT1XSdn33hPrqOY6DSWUVL7pDEapG03FREPV8,8419
69
69
  dashscope/threads/runs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- dashscope/threads/runs/runs.py,sha256=Fyny9GyCgxL0CRBht84f7sFjYKBwyZBC-HMCW1tx_3k,15529
70
+ dashscope/threads/runs/runs.py,sha256=Cvy5FD0x1Z9c5qayYeNpoL_QIqH4yxgqdGplCk3soRw,18762
71
71
  dashscope/threads/runs/steps.py,sha256=pLNR-5g7zvYkvC-p4sZGVgYHd1jqxBerM2WFyB358H8,3638
72
72
  dashscope/tokenizers/__init__.py,sha256=Oy5FMT37Non6e1YxdHQ89U93Dy3CG1Ez0gBa771KZo0,200
73
73
  dashscope/tokenizers/qwen_tokenizer.py,sha256=dCnT9-9NrqPS85bEhjlPULUfDADVRhlleYwM_ILgCeI,4111
@@ -76,9 +76,9 @@ dashscope/tokenizers/tokenizer.py,sha256=y6P91qTCYo__pEx_0VHAcj9YECfbUdRqZU1fdGT
76
76
  dashscope/tokenizers/tokenizer_base.py,sha256=REDhzRyDT13iequ61-a6_KcTy0GFKlihQve5HkyoyRs,656
77
77
  dashscope/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
78
  dashscope/utils/oss_utils.py,sha256=fi8-PPsN-iR-iv5k2NS5Z8nlWkpgUhr56FRWm4BDh4A,6984
79
- dashscope-1.17.1.dist-info/LICENSE,sha256=Izp5L1DF1Mbza6qojkqNNWlE_mYLnr4rmzx2EBF8YFw,11413
80
- dashscope-1.17.1.dist-info/METADATA,sha256=_T0MCoHE3S3mGMgFiK7nQvQo0gm48_X-S9H7VyxgrOM,6609
81
- dashscope-1.17.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
82
- dashscope-1.17.1.dist-info/entry_points.txt,sha256=raEp5dOuj8whJ7yqZlDM8WQ5p2RfnGrGNo0QLQEnatY,50
83
- dashscope-1.17.1.dist-info/top_level.txt,sha256=woqavFJK9zas5xTqynmALqOtlafghjsk63Xk86powTU,10
84
- dashscope-1.17.1.dist-info/RECORD,,
79
+ dashscope-1.18.1.dist-info/LICENSE,sha256=Izp5L1DF1Mbza6qojkqNNWlE_mYLnr4rmzx2EBF8YFw,11413
80
+ dashscope-1.18.1.dist-info/METADATA,sha256=33M-0CZybEgQltO9zFJSM4xHpCSEzO2IabuoaJJFbdI,6609
81
+ dashscope-1.18.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
82
+ dashscope-1.18.1.dist-info/entry_points.txt,sha256=raEp5dOuj8whJ7yqZlDM8WQ5p2RfnGrGNo0QLQEnatY,50
83
+ dashscope-1.18.1.dist-info/top_level.txt,sha256=woqavFJK9zas5xTqynmALqOtlafghjsk63Xk86powTU,10
84
+ dashscope-1.18.1.dist-info/RECORD,,