fabricatio 0.2.3.dev2__cp312-cp312-win_amd64.whl → 0.2.4.dev0__cp312-cp312-win_amd64.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.
fabricatio/config.py CHANGED
@@ -80,6 +80,33 @@ class LLMConfig(BaseModel):
80
80
  """The maximum number of tokens to generate. Set to 8192 as per request."""
81
81
 
82
82
 
83
+ class EmbeddingConfig(BaseModel):
84
+ """Embedding configuration class."""
85
+
86
+ model_config = ConfigDict(use_attribute_docstrings=True)
87
+
88
+ model: str = Field(default="text-embedding-ada-002")
89
+ """The embedding model name. """
90
+
91
+ dimensions: Optional[PositiveInt] = Field(default=None)
92
+ """The dimensions of the embedding. None means not checked."""
93
+
94
+ timeout: Optional[PositiveInt] = Field(default=None)
95
+ """The timeout of the embedding model in seconds."""
96
+
97
+ max_sequence_length: PositiveInt = Field(default=8192)
98
+ """The maximum sequence length of the embedding model. Default is 8192 as per request."""
99
+
100
+ caching: bool = Field(default=False)
101
+ """Whether to cache the embedding. Default is False."""
102
+
103
+ api_endpoint: Optional[HttpUrl] = None
104
+ """The OpenAI API endpoint."""
105
+
106
+ api_key: Optional[SecretStr] = None
107
+ """The OpenAI API key."""
108
+
109
+
83
110
  class PymitterConfig(BaseModel):
84
111
  """Pymitter configuration class.
85
112
 
@@ -140,8 +167,8 @@ class TemplateConfig(BaseModel):
140
167
  template_suffix: str = Field(default="hbs", frozen=True)
141
168
  """The suffix of the templates."""
142
169
 
143
- propose_task_template: str = Field(default="propose_task")
144
- """The name of the propose task template which will be used to propose a task."""
170
+ create_json_obj_template: str = Field(default="create_json_obj")
171
+ """The name of the create json object template which will be used to create a json object."""
145
172
 
146
173
  draft_tool_usage_code_template: str = Field(default="draft_tool_usage_code")
147
174
  """The name of the draft tool usage code template which will be used to draft tool usage code."""
@@ -176,6 +203,12 @@ class TemplateConfig(BaseModel):
176
203
  draft_rating_weights_klee_template: str = Field(default="draft_rating_weights_klee")
177
204
  """The name of the draft rating weights klee template which will be used to draft rating weights with Klee method."""
178
205
 
206
+ retrieved_display_template: str = Field(default="retrieved_display")
207
+ """The name of the retrieved display template which will be used to display retrieved documents."""
208
+
209
+ liststr_template: str = Field(default="liststr")
210
+ """The name of the liststr template which will be used to display a list of strings."""
211
+
179
212
 
180
213
  class MagikaConfig(BaseModel):
181
214
  """Magika configuration class."""
@@ -219,6 +252,8 @@ class RagConfig(BaseModel):
219
252
  """The timeout of the Milvus server."""
220
253
  milvus_token: Optional[SecretStr] = Field(default=None)
221
254
  """The token of the Milvus server."""
255
+ milvus_dimensions: Optional[PositiveInt] = Field(default=None)
256
+ """The dimensions of the Milvus server."""
222
257
 
223
258
 
224
259
  class Settings(BaseSettings):
@@ -246,6 +281,9 @@ class Settings(BaseSettings):
246
281
  llm: LLMConfig = Field(default_factory=LLMConfig)
247
282
  """LLM Configuration"""
248
283
 
284
+ embedding: EmbeddingConfig = Field(default_factory=EmbeddingConfig)
285
+ """Embedding Configuration"""
286
+
249
287
  debug: DebugConfig = Field(default_factory=DebugConfig)
250
288
  """Debug Configuration"""
251
289
 
@@ -46,6 +46,7 @@ class Action(HandleTask, ProposeTask, GiveRating):
46
46
  cxt[self.output_key] = ret
47
47
  return cxt
48
48
 
49
+ @property
49
50
  def briefing(self) -> str:
50
51
  """Return a brief description of the action."""
51
52
  if self.personality:
@@ -3,6 +3,7 @@
3
3
  from typing import List, Self, Union
4
4
 
5
5
  from fabricatio.config import configs
6
+ from fabricatio.models.utils import TaskStatus
6
7
  from pydantic import BaseModel, ConfigDict, Field
7
8
 
8
9
  type EventLike = Union[str, List[str], "Event"]
@@ -33,6 +34,21 @@ class Event(BaseModel):
33
34
 
34
35
  return cls(segments=event)
35
36
 
37
+ @classmethod
38
+ def quick_instantiate(cls, event: EventLike) -> Self:
39
+ """Create an Event instance from a string or list of strings or an Event instance and push a wildcard and pending segment.
40
+
41
+ Args:
42
+ event (EventLike): The event to instantiate from.
43
+
44
+ Returns:
45
+ Event: The Event instance.
46
+
47
+ Notes:
48
+ This method is used to create an Event instance from a string or list of strings or an Event instance and push a wildcard and pending segment.
49
+ """
50
+ return cls.instantiate_from(event).push_wildcard().push_pending()
51
+
36
52
  def derive(self, event: EventLike) -> Self:
37
53
  """Derive a new event from this event and another event or a string."""
38
54
  return self.clone().concat(event)
@@ -59,6 +75,26 @@ class Event(BaseModel):
59
75
  """Push a wildcard segment to the event."""
60
76
  return self.push("*")
61
77
 
78
+ def push_pending(self) -> Self:
79
+ """Push a pending segment to the event."""
80
+ return self.push(TaskStatus.Pending.value)
81
+
82
+ def push_running(self) -> Self:
83
+ """Push a running segment to the event."""
84
+ return self.push(TaskStatus.Running.value)
85
+
86
+ def push_finished(self) -> Self:
87
+ """Push a finished segment to the event."""
88
+ return self.push(TaskStatus.Finished.value)
89
+
90
+ def push_failed(self) -> Self:
91
+ """Push a failed segment to the event."""
92
+ return self.push(TaskStatus.Failed.value)
93
+
94
+ def push_cancelled(self) -> Self:
95
+ """Push a cancelled segment to the event."""
96
+ return self.push(TaskStatus.Cancelled.value)
97
+
62
98
  def pop(self) -> str:
63
99
  """Pop a segment from the event."""
64
100
  return self.segments.pop()
@@ -1,17 +1,23 @@
1
1
  """This module defines generic classes for models in the Fabricatio library."""
2
2
 
3
3
  from pathlib import Path
4
- from typing import Callable, List, Self
4
+ from typing import Callable, Iterable, List, Optional, Self, Union, final
5
5
 
6
6
  import orjson
7
7
  from fabricatio._rust import blake3_hash
8
8
  from fabricatio._rust_instances import template_manager
9
9
  from fabricatio.config import configs
10
10
  from fabricatio.fs.readers import magika, safe_text_read
11
+ from fabricatio.parser import JsonCapture
11
12
  from pydantic import (
12
13
  BaseModel,
13
14
  ConfigDict,
14
15
  Field,
16
+ HttpUrl,
17
+ NonNegativeFloat,
18
+ PositiveFloat,
19
+ PositiveInt,
20
+ SecretStr,
15
21
  )
16
22
 
17
23
 
@@ -48,22 +54,63 @@ class WithBriefing(Named, Described):
48
54
  return f"{self.name}: {self.description}" if self.description else self.name
49
55
 
50
56
 
51
- class WithJsonExample(Base):
52
- """Class that provides a JSON schema for the model."""
57
+ class WithFormatedJsonSchema(Base):
58
+ """Class that provides a formatted JSON schema of the model."""
53
59
 
54
60
  @classmethod
55
- def json_example(cls) -> str:
56
- """Return a JSON example for the model.
61
+ def formated_json_schema(cls) -> str:
62
+ """Get the JSON schema of the model in a formatted string.
57
63
 
58
64
  Returns:
59
- str: A JSON example for the model.
65
+ str: The JSON schema of the model in a formatted string.
60
66
  """
61
67
  return orjson.dumps(
62
- {field_name: field_info.description for field_name, field_info in cls.model_fields.items()},
68
+ cls.model_json_schema(),
63
69
  option=orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS,
64
70
  ).decode()
65
71
 
66
72
 
73
+ class CreateJsonObjPrompt(WithFormatedJsonSchema):
74
+ """Class that provides a prompt for creating a JSON object."""
75
+
76
+ @classmethod
77
+ def create_json_prompt(cls, requirement: str) -> str:
78
+ """Create the prompt for creating a JSON object with given requirement.
79
+
80
+ Args:
81
+ requirement (str): The requirement for the JSON object.
82
+
83
+ Returns:
84
+ str: The prompt for creating a JSON object with given requirement.
85
+ """
86
+ return template_manager.render_template(
87
+ configs.templates.create_json_obj_template,
88
+ {"requirement": requirement, "json_schema": cls.formated_json_schema()},
89
+ )
90
+
91
+
92
+ class InstantiateFromString(Base):
93
+ """Class that provides a method to instantiate the class from a string."""
94
+
95
+ @classmethod
96
+ def instantiate_from_string(cls, string: str) -> Self | None:
97
+ """Instantiate the class from a string.
98
+
99
+ Args:
100
+ string (str): The string to instantiate the class from.
101
+
102
+ Returns:
103
+ Self | None: The instance of the class or None if the string is not valid.
104
+ """
105
+ return JsonCapture.convert_with(string, cls.model_validate_json)
106
+
107
+
108
+ class ProposedAble(CreateJsonObjPrompt, InstantiateFromString):
109
+ """Class that provides methods for proposing a task."""
110
+
111
+ pass
112
+
113
+
67
114
  class WithDependency(Base):
68
115
  """Class that manages file dependencies."""
69
116
 
@@ -150,3 +197,107 @@ class WithDependency(Base):
150
197
  for p in self.dependencies
151
198
  },
152
199
  )
200
+
201
+
202
+ class ScopedConfig(Base):
203
+ """Class that manages a scoped configuration."""
204
+
205
+ llm_api_endpoint: Optional[HttpUrl] = None
206
+ """The OpenAI API endpoint."""
207
+
208
+ llm_api_key: Optional[SecretStr] = None
209
+ """The OpenAI API key."""
210
+
211
+ llm_timeout: Optional[PositiveInt] = None
212
+ """The timeout of the LLM model."""
213
+
214
+ llm_max_retries: Optional[PositiveInt] = None
215
+ """The maximum number of retries."""
216
+
217
+ llm_model: Optional[str] = None
218
+ """The LLM model name."""
219
+
220
+ llm_temperature: Optional[NonNegativeFloat] = None
221
+ """The temperature of the LLM model."""
222
+
223
+ llm_stop_sign: Optional[str | List[str]] = None
224
+ """The stop sign of the LLM model."""
225
+
226
+ llm_top_p: Optional[NonNegativeFloat] = None
227
+ """The top p of the LLM model."""
228
+
229
+ llm_generation_count: Optional[PositiveInt] = None
230
+ """The number of generations to generate."""
231
+
232
+ llm_stream: Optional[bool] = None
233
+ """Whether to stream the LLM model's response."""
234
+
235
+ llm_max_tokens: Optional[PositiveInt] = None
236
+ """The maximum number of tokens to generate."""
237
+
238
+ embedding_api_endpoint: Optional[HttpUrl] = None
239
+ """The OpenAI API endpoint."""
240
+
241
+ embedding_api_key: Optional[SecretStr] = None
242
+ """The OpenAI API key."""
243
+
244
+ embedding_timeout: Optional[PositiveInt] = None
245
+ """The timeout of the LLM model."""
246
+
247
+ embedding_model: Optional[str] = None
248
+ """The LLM model name."""
249
+
250
+ embedding_max_sequence_length: Optional[PositiveInt] = None
251
+ """The maximum sequence length."""
252
+
253
+ embedding_dimensions: Optional[PositiveInt] = None
254
+ """The dimensions of the embedding."""
255
+ embedding_caching: Optional[bool] = False
256
+ """Whether to cache the embedding result."""
257
+
258
+ milvus_uri: Optional[HttpUrl] = Field(default=None)
259
+ """The URI of the Milvus server."""
260
+ milvus_token: Optional[SecretStr] = Field(default=None)
261
+ """The token for the Milvus server."""
262
+ milvus_timeout: Optional[PositiveFloat] = Field(default=None)
263
+ """The timeout for the Milvus server."""
264
+ milvus_dimensions: Optional[PositiveInt] = Field(default=None)
265
+ """The dimensions of the Milvus server."""
266
+
267
+ @final
268
+ def fallback_to(self, other: "ScopedConfig") -> Self:
269
+ """Fallback to another instance's attribute values if the current instance's attributes are None.
270
+
271
+ Args:
272
+ other (LLMUsage): Another instance from which to copy attribute values.
273
+
274
+ Returns:
275
+ Self: The current instance, allowing for method chaining.
276
+ """
277
+ # Iterate over the attribute names and copy values from 'other' to 'self' where applicable
278
+ # noinspection PydanticTypeChecker,PyTypeChecker
279
+ for attr_name in ScopedConfig.model_fields:
280
+ # Copy the attribute value from 'other' to 'self' only if 'self' has None and 'other' has a non-None value
281
+ if getattr(self, attr_name) is None and (attr := getattr(other, attr_name)) is not None:
282
+ setattr(self, attr_name, attr)
283
+
284
+ # Return the current instance to allow for method chaining
285
+ return self
286
+
287
+ @final
288
+ def hold_to(self, others: Union["ScopedConfig", Iterable["ScopedConfig"]]) -> Self:
289
+ """Hold to another instance's attribute values if the current instance's attributes are None.
290
+
291
+ Args:
292
+ others (LLMUsage | Iterable[LLMUsage]): Another instance or iterable of instances from which to copy attribute values.
293
+
294
+ Returns:
295
+ Self: The current instance, allowing for method chaining.
296
+ """
297
+ if not isinstance(others, Iterable):
298
+ others = [others]
299
+ for other in others:
300
+ # noinspection PyTypeChecker,PydanticTypeChecker
301
+ for attr_name in ScopedConfig.model_fields:
302
+ if (attr := getattr(self, attr_name)) is not None and getattr(other, attr_name) is None:
303
+ setattr(other, attr_name, attr)
@@ -5,6 +5,20 @@ from typing import List, NotRequired, TypedDict
5
5
  from pydantic import NonNegativeFloat, NonNegativeInt, PositiveInt
6
6
 
7
7
 
8
+ class CollectionSimpleConfigKwargs(TypedDict):
9
+ """A type representing the configuration for a collection."""
10
+
11
+ dimension: NotRequired[int]
12
+ timeout: NotRequired[float]
13
+
14
+
15
+ class FetchKwargs(TypedDict):
16
+ """A type representing the keyword arguments for the fetch method."""
17
+
18
+ similarity_threshold: NotRequired[float]
19
+ result_per_query: NotRequired[int]
20
+
21
+
8
22
  class EmbeddingKwargs(TypedDict):
9
23
  """A type representing the keyword arguments for the embedding method."""
10
24
 
fabricatio/models/task.py CHANGED
@@ -4,7 +4,6 @@ It includes methods to manage the task's lifecycle, such as starting, finishing,
4
4
  """
5
5
 
6
6
  from asyncio import Queue
7
- from enum import Enum
8
7
  from typing import Any, List, Optional, Self
9
8
 
10
9
  from fabricatio._rust_instances import template_manager
@@ -12,53 +11,36 @@ from fabricatio.config import configs
12
11
  from fabricatio.core import env
13
12
  from fabricatio.journal import logger
14
13
  from fabricatio.models.events import Event, EventLike
15
- from fabricatio.models.generic import WithBriefing, WithDependency, WithJsonExample
14
+ from fabricatio.models.generic import ProposedAble, WithBriefing, WithDependency
15
+ from fabricatio.models.utils import TaskStatus
16
16
  from pydantic import Field, PrivateAttr
17
17
 
18
18
 
19
- class TaskStatus(Enum):
20
- """An enumeration representing the status of a task.
21
-
22
- Attributes:
23
- Pending: The task is pending.
24
- Running: The task is currently running.
25
- Finished: The task has been successfully completed.
26
- Failed: The task has failed.
27
- Cancelled: The task has been cancelled.
28
- """
29
-
30
- Pending = "pending"
31
- Running = "running"
32
- Finished = "finished"
33
- Failed = "failed"
34
- Cancelled = "cancelled"
35
-
36
-
37
- class Task[T](WithBriefing, WithJsonExample, WithDependency):
19
+ class Task[T](WithBriefing, ProposedAble, WithDependency):
38
20
  """A class representing a task with a status and output.
39
21
 
40
22
  Attributes:
41
23
  name (str): The name of the task.
42
24
  description (str): The description of the task.
43
- goal (str): The goal of the task.
25
+ goals (str): The goal of the task.
44
26
  dependencies (List[str]): The file dependencies of the task, a list of file paths.
45
27
  namespace (List[str]): The namespace of the task, a list of namespace segment, as string.
46
28
  """
47
29
 
48
30
  name: str = Field(...)
49
- """The name of the task, which should be a concise and descriptive name."""
31
+ """The name of the task, which should be concise and descriptive."""
50
32
 
51
33
  description: str = Field(default="")
52
- """The description of the task, which should provide every details and noting about the task if provided, obeying the CEFR level rule and 5W1H rule."""
34
+ """A detailed explanation of the task that includes all necessary information. Should be clear and answer what, why, when, where, who, and how questions."""
53
35
 
54
- goal: List[str] = Field(default=[])
55
- """The goal of the task, a list of strings. The goal should be a concise and clear statement of what the task is intended to achieve, goal SHALL NOT be too broad or too narrow."""
36
+ goals: List[str] = Field(default=[])
37
+ """A list of objectives that the task aims to accomplish. Each goal should be clear and specific. Complex tasks should be broken into multiple smaller goals."""
56
38
 
57
39
  namespace: List[str] = Field(default_factory=list)
58
- """The namespace of the task, a list of namespace segment, as string, if it is not directly given out, it SHALL just be a empty list meaning `NOT ASSIGNED`"""
40
+ """A list of string segments that identify the task's location in the system. If not specified, defaults to an empty list."""
59
41
 
60
42
  dependencies: List[str] = Field(default_factory=list)
61
- """A list of file paths, These file are needed to read or write to meet a specific requirement of this task, if it is not directly given out, it SHALL just be a empty list meaning `NOT ASSIGNED`"""
43
+ """A list of file paths that are needed or mentioned in the task's description (either reading or writing) to complete this task. If not specified, defaults to an empty list."""
62
44
 
63
45
  _output: Queue[T | None] = PrivateAttr(default_factory=Queue)
64
46
  """The output queue of the task."""
@@ -113,7 +95,7 @@ class Task[T](WithBriefing, WithJsonExample, WithDependency):
113
95
  Returns:
114
96
  Task: A new instance of the `Task` class.
115
97
  """
116
- return cls(name=name, goal=goal, description=description)
98
+ return cls(name=name, goals=goal, description=description)
117
99
 
118
100
  def update_task(self, goal: Optional[List[str] | str] = None, description: Optional[str] = None) -> Self:
119
101
  """Update the goal and description of the task.
@@ -126,7 +108,7 @@ class Task[T](WithBriefing, WithJsonExample, WithDependency):
126
108
  Task: The updated instance of the `Task` class.
127
109
  """
128
110
  if goal:
129
- self.goal = goal if isinstance(goal, list) else [goal]
111
+ self.goals = goal if isinstance(goal, list) else [goal]
130
112
  if description:
131
113
  self.description = description
132
114
  return self