kweaver-dolphin 0.1.0__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.
Files changed (199) hide show
  1. DolphinLanguageSDK/__init__.py +58 -0
  2. dolphin/__init__.py +62 -0
  3. dolphin/cli/__init__.py +20 -0
  4. dolphin/cli/args/__init__.py +9 -0
  5. dolphin/cli/args/parser.py +567 -0
  6. dolphin/cli/builtin_agents/__init__.py +22 -0
  7. dolphin/cli/commands/__init__.py +4 -0
  8. dolphin/cli/interrupt/__init__.py +8 -0
  9. dolphin/cli/interrupt/handler.py +205 -0
  10. dolphin/cli/interrupt/keyboard.py +82 -0
  11. dolphin/cli/main.py +49 -0
  12. dolphin/cli/multimodal/__init__.py +34 -0
  13. dolphin/cli/multimodal/clipboard.py +327 -0
  14. dolphin/cli/multimodal/handler.py +249 -0
  15. dolphin/cli/multimodal/image_processor.py +214 -0
  16. dolphin/cli/multimodal/input_parser.py +149 -0
  17. dolphin/cli/runner/__init__.py +8 -0
  18. dolphin/cli/runner/runner.py +989 -0
  19. dolphin/cli/ui/__init__.py +10 -0
  20. dolphin/cli/ui/console.py +2795 -0
  21. dolphin/cli/ui/input.py +340 -0
  22. dolphin/cli/ui/layout.py +425 -0
  23. dolphin/cli/ui/stream_renderer.py +302 -0
  24. dolphin/cli/utils/__init__.py +8 -0
  25. dolphin/cli/utils/helpers.py +135 -0
  26. dolphin/cli/utils/version.py +49 -0
  27. dolphin/core/__init__.py +107 -0
  28. dolphin/core/agent/__init__.py +10 -0
  29. dolphin/core/agent/agent_state.py +69 -0
  30. dolphin/core/agent/base_agent.py +970 -0
  31. dolphin/core/code_block/__init__.py +0 -0
  32. dolphin/core/code_block/agent_init_block.py +0 -0
  33. dolphin/core/code_block/assign_block.py +98 -0
  34. dolphin/core/code_block/basic_code_block.py +1865 -0
  35. dolphin/core/code_block/explore_block.py +1327 -0
  36. dolphin/core/code_block/explore_block_v2.py +712 -0
  37. dolphin/core/code_block/explore_strategy.py +672 -0
  38. dolphin/core/code_block/judge_block.py +220 -0
  39. dolphin/core/code_block/prompt_block.py +32 -0
  40. dolphin/core/code_block/skill_call_deduplicator.py +291 -0
  41. dolphin/core/code_block/tool_block.py +129 -0
  42. dolphin/core/common/__init__.py +17 -0
  43. dolphin/core/common/constants.py +176 -0
  44. dolphin/core/common/enums.py +1173 -0
  45. dolphin/core/common/exceptions.py +133 -0
  46. dolphin/core/common/multimodal.py +539 -0
  47. dolphin/core/common/object_type.py +165 -0
  48. dolphin/core/common/output_format.py +432 -0
  49. dolphin/core/common/types.py +36 -0
  50. dolphin/core/config/__init__.py +16 -0
  51. dolphin/core/config/global_config.py +1289 -0
  52. dolphin/core/config/ontology_config.py +133 -0
  53. dolphin/core/context/__init__.py +12 -0
  54. dolphin/core/context/context.py +1580 -0
  55. dolphin/core/context/context_manager.py +161 -0
  56. dolphin/core/context/var_output.py +82 -0
  57. dolphin/core/context/variable_pool.py +356 -0
  58. dolphin/core/context_engineer/__init__.py +41 -0
  59. dolphin/core/context_engineer/config/__init__.py +5 -0
  60. dolphin/core/context_engineer/config/settings.py +402 -0
  61. dolphin/core/context_engineer/core/__init__.py +7 -0
  62. dolphin/core/context_engineer/core/budget_manager.py +327 -0
  63. dolphin/core/context_engineer/core/context_assembler.py +583 -0
  64. dolphin/core/context_engineer/core/context_manager.py +637 -0
  65. dolphin/core/context_engineer/core/tokenizer_service.py +260 -0
  66. dolphin/core/context_engineer/example/incremental_example.py +267 -0
  67. dolphin/core/context_engineer/example/traditional_example.py +334 -0
  68. dolphin/core/context_engineer/services/__init__.py +5 -0
  69. dolphin/core/context_engineer/services/compressor.py +399 -0
  70. dolphin/core/context_engineer/utils/__init__.py +6 -0
  71. dolphin/core/context_engineer/utils/context_utils.py +441 -0
  72. dolphin/core/context_engineer/utils/message_formatter.py +270 -0
  73. dolphin/core/context_engineer/utils/token_utils.py +139 -0
  74. dolphin/core/coroutine/__init__.py +15 -0
  75. dolphin/core/coroutine/context_snapshot.py +154 -0
  76. dolphin/core/coroutine/context_snapshot_profile.py +922 -0
  77. dolphin/core/coroutine/context_snapshot_store.py +268 -0
  78. dolphin/core/coroutine/execution_frame.py +145 -0
  79. dolphin/core/coroutine/execution_state_registry.py +161 -0
  80. dolphin/core/coroutine/resume_handle.py +101 -0
  81. dolphin/core/coroutine/step_result.py +101 -0
  82. dolphin/core/executor/__init__.py +18 -0
  83. dolphin/core/executor/debug_controller.py +630 -0
  84. dolphin/core/executor/dolphin_executor.py +1063 -0
  85. dolphin/core/executor/executor.py +624 -0
  86. dolphin/core/flags/__init__.py +27 -0
  87. dolphin/core/flags/definitions.py +49 -0
  88. dolphin/core/flags/manager.py +113 -0
  89. dolphin/core/hook/__init__.py +95 -0
  90. dolphin/core/hook/expression_evaluator.py +499 -0
  91. dolphin/core/hook/hook_dispatcher.py +380 -0
  92. dolphin/core/hook/hook_types.py +248 -0
  93. dolphin/core/hook/isolated_variable_pool.py +284 -0
  94. dolphin/core/interfaces.py +53 -0
  95. dolphin/core/llm/__init__.py +0 -0
  96. dolphin/core/llm/llm.py +495 -0
  97. dolphin/core/llm/llm_call.py +100 -0
  98. dolphin/core/llm/llm_client.py +1285 -0
  99. dolphin/core/llm/message_sanitizer.py +120 -0
  100. dolphin/core/logging/__init__.py +20 -0
  101. dolphin/core/logging/logger.py +526 -0
  102. dolphin/core/message/__init__.py +8 -0
  103. dolphin/core/message/compressor.py +749 -0
  104. dolphin/core/parser/__init__.py +8 -0
  105. dolphin/core/parser/parser.py +405 -0
  106. dolphin/core/runtime/__init__.py +10 -0
  107. dolphin/core/runtime/runtime_graph.py +926 -0
  108. dolphin/core/runtime/runtime_instance.py +446 -0
  109. dolphin/core/skill/__init__.py +14 -0
  110. dolphin/core/skill/context_retention.py +157 -0
  111. dolphin/core/skill/skill_function.py +686 -0
  112. dolphin/core/skill/skill_matcher.py +282 -0
  113. dolphin/core/skill/skillkit.py +700 -0
  114. dolphin/core/skill/skillset.py +72 -0
  115. dolphin/core/trajectory/__init__.py +10 -0
  116. dolphin/core/trajectory/recorder.py +189 -0
  117. dolphin/core/trajectory/trajectory.py +522 -0
  118. dolphin/core/utils/__init__.py +9 -0
  119. dolphin/core/utils/cache_kv.py +212 -0
  120. dolphin/core/utils/tools.py +340 -0
  121. dolphin/lib/__init__.py +93 -0
  122. dolphin/lib/debug/__init__.py +8 -0
  123. dolphin/lib/debug/visualizer.py +409 -0
  124. dolphin/lib/memory/__init__.py +28 -0
  125. dolphin/lib/memory/async_processor.py +220 -0
  126. dolphin/lib/memory/llm_calls.py +195 -0
  127. dolphin/lib/memory/manager.py +78 -0
  128. dolphin/lib/memory/sandbox.py +46 -0
  129. dolphin/lib/memory/storage.py +245 -0
  130. dolphin/lib/memory/utils.py +51 -0
  131. dolphin/lib/ontology/__init__.py +12 -0
  132. dolphin/lib/ontology/basic/__init__.py +0 -0
  133. dolphin/lib/ontology/basic/base.py +102 -0
  134. dolphin/lib/ontology/basic/concept.py +130 -0
  135. dolphin/lib/ontology/basic/object.py +11 -0
  136. dolphin/lib/ontology/basic/relation.py +63 -0
  137. dolphin/lib/ontology/datasource/__init__.py +27 -0
  138. dolphin/lib/ontology/datasource/datasource.py +66 -0
  139. dolphin/lib/ontology/datasource/oracle_datasource.py +338 -0
  140. dolphin/lib/ontology/datasource/sql.py +845 -0
  141. dolphin/lib/ontology/mapping.py +177 -0
  142. dolphin/lib/ontology/ontology.py +733 -0
  143. dolphin/lib/ontology/ontology_context.py +16 -0
  144. dolphin/lib/ontology/ontology_manager.py +107 -0
  145. dolphin/lib/skill_results/__init__.py +31 -0
  146. dolphin/lib/skill_results/cache_backend.py +559 -0
  147. dolphin/lib/skill_results/result_processor.py +181 -0
  148. dolphin/lib/skill_results/result_reference.py +179 -0
  149. dolphin/lib/skill_results/skillkit_hook.py +324 -0
  150. dolphin/lib/skill_results/strategies.py +328 -0
  151. dolphin/lib/skill_results/strategy_registry.py +150 -0
  152. dolphin/lib/skillkits/__init__.py +44 -0
  153. dolphin/lib/skillkits/agent_skillkit.py +155 -0
  154. dolphin/lib/skillkits/cognitive_skillkit.py +82 -0
  155. dolphin/lib/skillkits/env_skillkit.py +250 -0
  156. dolphin/lib/skillkits/mcp_adapter.py +616 -0
  157. dolphin/lib/skillkits/mcp_skillkit.py +771 -0
  158. dolphin/lib/skillkits/memory_skillkit.py +650 -0
  159. dolphin/lib/skillkits/noop_skillkit.py +31 -0
  160. dolphin/lib/skillkits/ontology_skillkit.py +89 -0
  161. dolphin/lib/skillkits/plan_act_skillkit.py +452 -0
  162. dolphin/lib/skillkits/resource/__init__.py +52 -0
  163. dolphin/lib/skillkits/resource/models/__init__.py +6 -0
  164. dolphin/lib/skillkits/resource/models/skill_config.py +109 -0
  165. dolphin/lib/skillkits/resource/models/skill_meta.py +127 -0
  166. dolphin/lib/skillkits/resource/resource_skillkit.py +393 -0
  167. dolphin/lib/skillkits/resource/skill_cache.py +215 -0
  168. dolphin/lib/skillkits/resource/skill_loader.py +395 -0
  169. dolphin/lib/skillkits/resource/skill_validator.py +406 -0
  170. dolphin/lib/skillkits/resource_skillkit.py +11 -0
  171. dolphin/lib/skillkits/search_skillkit.py +163 -0
  172. dolphin/lib/skillkits/sql_skillkit.py +274 -0
  173. dolphin/lib/skillkits/system_skillkit.py +509 -0
  174. dolphin/lib/skillkits/vm_skillkit.py +65 -0
  175. dolphin/lib/utils/__init__.py +9 -0
  176. dolphin/lib/utils/data_process.py +207 -0
  177. dolphin/lib/utils/handle_progress.py +178 -0
  178. dolphin/lib/utils/security.py +139 -0
  179. dolphin/lib/utils/text_retrieval.py +462 -0
  180. dolphin/lib/vm/__init__.py +11 -0
  181. dolphin/lib/vm/env_executor.py +895 -0
  182. dolphin/lib/vm/python_session_manager.py +453 -0
  183. dolphin/lib/vm/vm.py +610 -0
  184. dolphin/sdk/__init__.py +60 -0
  185. dolphin/sdk/agent/__init__.py +12 -0
  186. dolphin/sdk/agent/agent_factory.py +236 -0
  187. dolphin/sdk/agent/dolphin_agent.py +1106 -0
  188. dolphin/sdk/api/__init__.py +4 -0
  189. dolphin/sdk/runtime/__init__.py +8 -0
  190. dolphin/sdk/runtime/env.py +363 -0
  191. dolphin/sdk/skill/__init__.py +10 -0
  192. dolphin/sdk/skill/global_skills.py +706 -0
  193. dolphin/sdk/skill/traditional_toolkit.py +260 -0
  194. kweaver_dolphin-0.1.0.dist-info/METADATA +521 -0
  195. kweaver_dolphin-0.1.0.dist-info/RECORD +199 -0
  196. kweaver_dolphin-0.1.0.dist-info/WHEEL +5 -0
  197. kweaver_dolphin-0.1.0.dist-info/entry_points.txt +27 -0
  198. kweaver_dolphin-0.1.0.dist-info/licenses/LICENSE.txt +201 -0
  199. kweaver_dolphin-0.1.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,165 @@
1
+ import json
2
+ import os
3
+ from typing import Dict, Any, List, Optional
4
+
5
+
6
+ class ObjectType:
7
+ def __init__(
8
+ self,
9
+ title: str,
10
+ description: str,
11
+ properties: Dict[str, Dict[str, Any]],
12
+ required: List[str],
13
+ ):
14
+ self.title: str = title
15
+ self.description: str = description
16
+ self.properties: Dict[str, Dict[str, Any]] = properties
17
+ self.required: List[str] = required
18
+
19
+ @classmethod
20
+ def load(cls, jsonData: Dict[str, Any]) -> "ObjectType":
21
+ """
22
+ Load and validate ObjectType from JSON data.
23
+
24
+ Args:
25
+ jsonData: Dictionary representing the ObjectType.
26
+
27
+ Returns:
28
+ An ObjectType instance.
29
+
30
+ Raises:
31
+ ValueError: If the JSON data format is invalid.
32
+ """
33
+ requiredFields = ["title", "description", "type", "properties"]
34
+ for field in requiredFields:
35
+ if field not in jsonData:
36
+ raise ValueError(f"Missing required field: {field}")
37
+
38
+ if jsonData.get("type") != "object":
39
+ raise ValueError(f"Type must be 'object', but got '{jsonData.get('type')}'")
40
+
41
+ title = jsonData["title"]
42
+ description = jsonData["description"]
43
+ properties = jsonData["properties"]
44
+ required = jsonData.get(
45
+ "required", []
46
+ ) # required is optional, but should be a list if present
47
+
48
+ if not isinstance(title, str) or not title:
49
+ raise ValueError("Field 'title' must be a non-empty string")
50
+ if not isinstance(description, str):
51
+ raise ValueError("Field 'description' must be a string")
52
+ if not isinstance(properties, dict):
53
+ raise ValueError("Field 'properties' must be a dictionary")
54
+ if not isinstance(required, list):
55
+ raise ValueError("Field 'required' must be a list")
56
+
57
+ # Validate properties structure and required list
58
+ for propName, propData in properties.items():
59
+ if not isinstance(propData, dict):
60
+ raise ValueError(f"Value of property '{propName}' must be a dictionary")
61
+ if "type" not in propData or not isinstance(propData["type"], str):
62
+ raise ValueError(
63
+ f"Property '{propName}' is missing or has an invalid 'type' field"
64
+ )
65
+ # Further validation based on type could be added here
66
+ if "description" not in propData or not isinstance(
67
+ propData["description"], str
68
+ ):
69
+ raise ValueError(
70
+ f"Property '{propName}' is missing or has an invalid 'description' field"
71
+ )
72
+
73
+ for reqProp in required:
74
+ if reqProp not in properties:
75
+ raise ValueError(
76
+ f"Required property '{reqProp}' is not defined in properties"
77
+ )
78
+
79
+ return cls(
80
+ title=title,
81
+ description=description,
82
+ properties=properties,
83
+ required=required,
84
+ )
85
+
86
+
87
+ class ObjectTypeFactory:
88
+ def __init__(self):
89
+ self.objectTypes: Dict[str, ObjectType] = {}
90
+
91
+ def load_from_json(self, json_data: Dict[str, Any]):
92
+ try:
93
+ objectTypeInstance = ObjectType.load(json_data)
94
+ self.objectTypes[objectTypeInstance.title] = objectTypeInstance
95
+ except Exception as e:
96
+ raise Exception(
97
+ f"An unexpected error occurred while loading ObjectType from {json_data}: {e}"
98
+ ) from e
99
+
100
+ def load(self, filepath: str):
101
+ """
102
+ Load an ObjectType from the specified .type file.
103
+
104
+ Args:
105
+ filepath: The path to the .type file.
106
+
107
+ Raises:
108
+ FileNotFoundError: If the file does not exist or is not a file.
109
+ ValueError: If the file content is not valid JSON or the ObjectType definition is invalid.
110
+ json.JSONDecodeError: If the file content is not valid JSON.
111
+ Exception: For other unexpected errors during file processing.
112
+ """
113
+ if not os.path.isfile(filepath):
114
+ raise FileNotFoundError(f"File not found or is not a file: {filepath}")
115
+
116
+ with open(filepath, "r", encoding="utf-8") as f:
117
+ jsonData = json.load(f)
118
+
119
+ self.load_from_json(jsonData)
120
+
121
+ def getTypes(self, titles: Optional[List[str]] = None) -> List[ObjectType]:
122
+ """
123
+ Get all loaded ObjectType instances.
124
+
125
+ Returns:
126
+ A list of all loaded ObjectType instances.
127
+ """
128
+ if titles is None:
129
+ return list(self.objectTypes.values())
130
+ else:
131
+ for title in titles:
132
+ if title not in self.objectTypes:
133
+ raise ValueError(f"ObjectType title '{title}' not found")
134
+ return [self.objectTypes[title] for title in titles]
135
+
136
+ @staticmethod
137
+ def getOpenaiJsonSchema(objectTypes: List[ObjectType]) -> Dict[str, Any]:
138
+ """
139
+ Convert a list of ObjectType instances to OpenAI JSON Schema format.
140
+
141
+ Args:
142
+ objectTypes: A list of ObjectType instances.
143
+
144
+ Returns:
145
+ A string representing the OpenAI JSON Schema for tools/functions.
146
+ """
147
+ schemas = []
148
+ for objectType in objectTypes:
149
+ schema = {
150
+ "type": "function",
151
+ "function": {
152
+ "name": objectType.title,
153
+ "description": objectType.description,
154
+ "parameters": {
155
+ "type": "object",
156
+ "properties": objectType.properties,
157
+ },
158
+ },
159
+ }
160
+ # Only include 'required' key if the list is not empty
161
+ if objectType.required:
162
+ schema["function"]["parameters"]["required"] = objectType.required
163
+
164
+ schemas.append(schema)
165
+ return schemas
@@ -0,0 +1,432 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Dict, Any, List
3
+ from enum import Enum
4
+
5
+ from dolphin.core.common.enums import MessageRole
6
+
7
+ # Import existing JSON utilities
8
+ from dolphin.core.utils.tools import (
9
+ safe_json_loads,
10
+ )
11
+ from dolphin.core.logging.logger import get_logger
12
+
13
+ logger = get_logger("type")
14
+
15
+
16
+ class OutputFormatType(Enum):
17
+ """Enum for output format types"""
18
+
19
+ JSON = "json"
20
+ JSONL = "jsonl"
21
+ OBJECT = "object"
22
+ LIST_STR = "list_str"
23
+
24
+
25
+ class OutputFormat(ABC):
26
+ """Abstract base class for output format
27
+
28
+ Defines the standard interface for output format handling:
29
+ 1. Add format constraint prompts
30
+ 2. Parse response results
31
+ 3. Get format description information
32
+ """
33
+
34
+ def __init__(self, formatType: OutputFormatType):
35
+ """Initialize output format
36
+
37
+ Args:
38
+ formatType: Output format type
39
+ """
40
+ self.formatType = formatType
41
+
42
+ @abstractmethod
43
+ def addFormatConstraintToMessages(self, messages) -> None:
44
+ """Add format constraint prompts to Messages
45
+
46
+ Args:
47
+ messages: Messages object, used to add format constraint prompts
48
+ """
49
+ pass
50
+
51
+ @abstractmethod
52
+ def parseResponse(self, responseStr: str) -> Any:
53
+ """Parse the response string into the corresponding data structure
54
+
55
+ Args:
56
+ responseStr: The string of the LLM response
57
+
58
+ Returns:
59
+ The parsed data structure
60
+ """
61
+ pass
62
+
63
+ @abstractmethod
64
+ def getFormatDescription(self) -> str:
65
+ """Get the format description for explaining output format requirements to users.
66
+
67
+ Returns:
68
+ Format description string
69
+ """
70
+ pass
71
+
72
+ def getFormatType(self) -> OutputFormatType:
73
+ """Get output format type"""
74
+ return self.formatType
75
+
76
+ def toDict(self) -> Dict[str, Any]:
77
+ """Convert the output format to dictionary format
78
+
79
+ Returns:
80
+ Dictionary representation of format information
81
+ """
82
+ return {"format_type": self.formatType.value}
83
+
84
+ def __str__(self) -> str:
85
+ """String Representation"""
86
+ return self.formatType.value
87
+
88
+ def __repr__(self) -> str:
89
+ """Debug string representation"""
90
+ return f"{self.__class__.__name__}(format={self.formatType.value})"
91
+
92
+
93
+ class JsonOutputFormat(OutputFormat):
94
+ """JSON format output processor"""
95
+
96
+ def __init__(self):
97
+ super().__init__(OutputFormatType.JSON)
98
+
99
+ def addFormatConstraintToMessages(self, messages) -> None:
100
+ """Add JSON format constraints to Messages"""
101
+ constraint_message = (
102
+ "请以标准 JSON 格式输出结果。确保输出是有效的 JSON 对象,"
103
+ "不要包含任何额外的文本说明或代码块标记。"
104
+ )
105
+ messages.append_message(MessageRole.USER, constraint_message)
106
+
107
+ def parseResponse(self, responseStr: str) -> Dict[str, Any]:
108
+ """Parse JSON response into a dictionary
109
+
110
+ Args:
111
+ responseStr: Response string
112
+
113
+ Returns:
114
+ Parsed dictionary object
115
+
116
+ Raises:
117
+ ValueError: If JSON parsing fails
118
+ """
119
+ from dolphin.core.utils.tools import extract_json
120
+
121
+ result = extract_json(responseStr)
122
+ if result is None:
123
+ logger.error("Failed to parse JSON response")
124
+ logger.error(f"Response content: {responseStr}")
125
+ raise ValueError("Invalid JSON format in response")
126
+
127
+ return result
128
+
129
+ def getFormatDescription(self) -> str:
130
+ """Get JSON format description"""
131
+ return "输出格式:标准 JSON 对象"
132
+
133
+
134
+ class JsonlOutputFormat(OutputFormat):
135
+ """JSONL format output processor"""
136
+
137
+ def __init__(self):
138
+ super().__init__(OutputFormatType.JSONL)
139
+
140
+ def addFormatConstraintToMessages(self, messages) -> None:
141
+ """Add JSONL format constraints to Messages"""
142
+ constraint_message = "请以 JSON Lines (JSONL) 格式输出结果,不要包含任何额外的文本说明或代码块标记。"
143
+ messages.append_message(MessageRole.USER, constraint_message)
144
+
145
+ def parseResponse(self, responseStr: str) -> List[Dict[str, Any]]:
146
+ """Parse JSONL response into a list of dictionaries
147
+
148
+ Args:
149
+ responseStr: Response string
150
+
151
+ Returns:
152
+ List of parsed dictionaries
153
+
154
+ Raises:
155
+ ValueError: If JSONL parsing fails
156
+ """
157
+ from dolphin.core.utils.tools import extract_jsonl
158
+
159
+ results = extract_jsonl(responseStr)
160
+ if results is None:
161
+ logger.error("Failed to parse JSONL response")
162
+ logger.error(f"Response content: {responseStr}")
163
+ raise ValueError("Invalid JSONL format in response")
164
+ return results
165
+
166
+ def getFormatDescription(self) -> str:
167
+ """Get JSONL format description"""
168
+ return "输出格式:JSON Lines,每行一个 JSON 对象"
169
+
170
+
171
+ class ListStrOutputFormat(OutputFormat):
172
+ """List string format output processor, output format is List[str]"""
173
+
174
+ def __init__(self):
175
+ super().__init__(OutputFormatType.LIST_STR)
176
+
177
+ def addFormatConstraintToMessages(self, messages) -> None:
178
+ """Add list string format constraints to Messages"""
179
+ constraint_message = (
180
+ "请以字符串列表格式输出结果。输出一个包含多个字符串元素的列表,"
181
+ '格式为JSON数组,每个元素都是字符串类型,例如:["item1", "item2", "item3"]。'
182
+ "不要包含任何额外的文本说明或代码块标记。"
183
+ )
184
+ messages.append_message(MessageRole.USER, constraint_message)
185
+
186
+ def parseResponse(self, responseStr: str) -> List[str]:
187
+ """Parse a list string response into a string list
188
+
189
+ Args:
190
+ responseStr: Response string
191
+
192
+ Returns:
193
+ Parsed string list
194
+
195
+ Raises:
196
+ ValueError: If list parsing fails
197
+ """
198
+ # Try to parse directly as JSON
199
+ try:
200
+ result = safe_json_loads(responseStr.strip())
201
+ if isinstance(result, list) and all(
202
+ isinstance(item, str) for item in result
203
+ ):
204
+ return result
205
+ else:
206
+ # If not a list of strings, attempt to convert to a list of strings
207
+ if isinstance(result, list):
208
+ return [str(item) for item in result]
209
+ else:
210
+ raise ValueError("Response is not a list")
211
+ except ValueError:
212
+ # Direct parsing failed, try extracting JSON content
213
+ pass
214
+
215
+ # Try to extract a JSON array from the response
216
+ try:
217
+ from dolphin.core.utils.tools import extract_json
218
+
219
+ result = extract_json(responseStr)
220
+ if isinstance(result, list):
221
+ # Ensure all elements are strings
222
+ return [str(item) for item in result]
223
+ else:
224
+ raise ValueError("Extracted content is not a list")
225
+ except ValueError:
226
+ pass
227
+
228
+ # If JSON parsing fails, try simple line splitting
229
+ logger.warning("Failed to parse as JSON list, attempting line-based parsing")
230
+ lines = [
231
+ line.strip() for line in responseStr.strip().split("\n") if line.strip()
232
+ ]
233
+ if lines:
234
+ return lines
235
+
236
+ # Fallback: Return the original response as a list of a single string
237
+ logger.warning(
238
+ "All parsing methods failed, returning response as single string list"
239
+ )
240
+ return [responseStr.strip()]
241
+
242
+ def getFormatDescription(self) -> str:
243
+ """Get list string format description"""
244
+ return "输出格式:字符串列表 List[str]"
245
+
246
+
247
+ class ObjectTypeOutputFormat(OutputFormat):
248
+ """Object type format output processor"""
249
+
250
+ def __init__(self, objectTypeName: str, objectTypeDefinition: Dict[str, Any]):
251
+ """Initialize object type output format
252
+
253
+ Args:
254
+ objectTypeName: Object type name
255
+ objectTypeDefinition: Object type definition
256
+ """
257
+ super().__init__(OutputFormatType.OBJECT)
258
+ self.objectTypeName = objectTypeName
259
+ self.objectTypeDefinition = objectTypeDefinition
260
+
261
+ def addFormatConstraintToMessages(self, messages) -> None:
262
+ """Add object type format constraints to Messages"""
263
+ constraint_message = self._buildConstraintMessage()
264
+ messages.append_message(MessageRole.USER, constraint_message)
265
+
266
+ def _buildConstraintMessage(self) -> str:
267
+ """Build object type format constraint message
268
+
269
+ For ObjectType format, the specific schema is passed through function call tools,
270
+ here we only need to indicate that tool invocation should be used
271
+ """
272
+ return f"请使用 {self.objectTypeName} 工具调用来生成结构化输出。"
273
+
274
+ def generateFunctionCallTools(self) -> List[Dict[str, Any]]:
275
+ """Generate the tools parameter value for function_call
276
+
277
+ Returns:
278
+ List of tool definitions, used for LLM's function_call
279
+ """
280
+ if not self.objectTypeDefinition:
281
+ raise ValueError(
282
+ f"Object type definition not found for '{self.objectTypeName}'"
283
+ )
284
+
285
+ tool_definition = {
286
+ "type": "function",
287
+ "function": {
288
+ "name": self.objectTypeName,
289
+ "description": self.objectTypeDefinition.get(
290
+ "description", f"{self.objectTypeName} object"
291
+ ),
292
+ "parameters": {
293
+ "type": "object",
294
+ "properties": self.objectTypeDefinition.get("properties", {}),
295
+ },
296
+ },
297
+ }
298
+
299
+ # Only add when the required list is not empty
300
+ required = self.objectTypeDefinition.get("required", [])
301
+ if required:
302
+ tool_definition["function"]["parameters"]["required"] = required
303
+
304
+ return [tool_definition]
305
+
306
+ def parseResponse(self, responseStr: str) -> Dict[str, Any]:
307
+ """Parse object type response
308
+
309
+ For object types, the response is usually the parameter of function_call,
310
+ but it may also be a JSON-formatted object definition.
311
+
312
+ Args:
313
+ responseStr: Response string
314
+
315
+ Returns:
316
+ Parsed object
317
+ """
318
+ try:
319
+ from dolphin.core.utils.tools import extract_json
320
+
321
+ return extract_json(responseStr)
322
+ except ValueError:
323
+ # Both JSON extraction and parsing have failed, return the original string as the content field.
324
+ pass
325
+
326
+ # If parsing fails, return the original string as the content field
327
+ logger.warning(
328
+ "Failed to parse object type response as JSON, returning as text content"
329
+ )
330
+ return {"content": responseStr}
331
+
332
+ def getFormatDescription(self) -> str:
333
+ """Get object type format description"""
334
+ return f"输出格式:{self.objectTypeName} 对象类型"
335
+
336
+ def getObjectTypeName(self) -> str:
337
+ """Get object type name"""
338
+ return self.objectTypeName
339
+
340
+ def getObjectTypeDefinition(self) -> Dict[str, Any]:
341
+ """Get object type definition"""
342
+ return self.objectTypeDefinition
343
+
344
+ def toDict(self) -> Dict[str, Any]:
345
+ """Convert the output format to dictionary format"""
346
+ result = super().toDict()
347
+ result.update(
348
+ {
349
+ "object_type_name": self.objectTypeName,
350
+ "object_type_definition": self.objectTypeDefinition,
351
+ }
352
+ )
353
+ return result
354
+
355
+
356
+ class OutputFormatFactory:
357
+ """Format factory class"""
358
+
359
+ @staticmethod
360
+ def parseFromString(outputValue: str, globalTypes=None) -> OutputFormat:
361
+ """Parse output format from string
362
+
363
+ Args:
364
+ outputValue: Output format string, such as "json", "jsonl", "obj/UserProfile"
365
+ globalTypes: ObjectTypeFactory instance, used to retrieve object type definitions
366
+
367
+ Returns:
368
+ An OutputFormat instance
369
+
370
+ Raises:
371
+ ValueError: When the format is invalid or the object type does not exist
372
+ """
373
+ if not outputValue or not outputValue.strip():
374
+ raise ValueError("Output format value cannot be empty")
375
+
376
+ outputValue = outputValue.strip().strip('"').strip("'")
377
+
378
+ # Processing JSON format
379
+ if outputValue.lower() == "json":
380
+ return JsonOutputFormat()
381
+
382
+ # Processing JSONL format
383
+ elif outputValue.lower() == "jsonl":
384
+ return JsonlOutputFormat()
385
+
386
+ # Process list string format
387
+ elif outputValue.lower() == "list_str":
388
+ return ListStrOutputFormat()
389
+
390
+ # Object type format: obj/TypeName
391
+ elif outputValue.startswith("obj/"):
392
+ objectTypeName = outputValue[4:] # Remove the "obj/" prefix
393
+
394
+ if not objectTypeName:
395
+ raise ValueError(
396
+ "Object type name cannot be empty in 'obj/TypeName' format"
397
+ )
398
+
399
+ # Get type definitions from global_types
400
+ objectTypeDefinition = None
401
+ if globalTypes:
402
+ try:
403
+ objectTypes = globalTypes.getTypes([objectTypeName])
404
+ if objectTypes:
405
+ objectType = objectTypes[0]
406
+ objectTypeDefinition = {
407
+ "title": objectType.title,
408
+ "description": objectType.description,
409
+ "type": "object",
410
+ "properties": objectType.properties,
411
+ "required": objectType.required,
412
+ }
413
+ except Exception as e:
414
+ logger.warning(
415
+ f"Failed to get object type '{objectTypeName}' from global_types: {e}"
416
+ )
417
+ raise ValueError(
418
+ f"Object type '{objectTypeName}' not found in global_types"
419
+ )
420
+ else:
421
+ logger.warning(
422
+ "global_types not provided, object type definition will be None"
423
+ )
424
+ raise ValueError("global_types is required for object type format")
425
+
426
+ return ObjectTypeOutputFormat(objectTypeName, objectTypeDefinition)
427
+
428
+ else:
429
+ raise ValueError(
430
+ f"Invalid output format: '{outputValue}'. "
431
+ + "Supported formats: 'json', 'jsonl', 'list_str', 'obj/TypeName'"
432
+ )
@@ -0,0 +1,36 @@
1
+ from abc import abstractmethod
2
+ from enum import Enum
3
+
4
+
5
+ class SourceType(Enum):
6
+ SKILL = "SKILL"
7
+ LLM = "LLM"
8
+ EXPLORE = "EXPLORE"
9
+ ASSIGN = "ASSIGN"
10
+ LIST = "LIST"
11
+ OTHER = "OTHER"
12
+
13
+
14
+ class Var:
15
+ def __init__(self, value):
16
+ self.val = value
17
+
18
+ @abstractmethod
19
+ def add(self, var: "Var") -> "Var":
20
+ raise NotImplementedError
21
+
22
+ @abstractmethod
23
+ def set_last(self, var: "Var") -> "Var":
24
+ raise NotImplementedError
25
+
26
+ @property
27
+ def value(self):
28
+ return self.val
29
+
30
+ def to_dict(self):
31
+ return self.val
32
+
33
+
34
+ # Note: ObjectType, ObjectTypeFactory, OutputFormat, etc. are available
35
+ # from dolphin.core.common.object_type and dolphin.core.common.output_format
36
+ # They are NOT re-exported here to avoid circular imports with enums.py
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Config 模块 - 核心配置"""
3
+
4
+ from dolphin.core.config.global_config import GlobalConfig
5
+ from dolphin.core.config.ontology_config import (
6
+ DataSourceType,
7
+ DataSourceConfig,
8
+ OntologyConfig,
9
+ )
10
+
11
+ __all__ = [
12
+ "GlobalConfig",
13
+ "DataSourceType",
14
+ "DataSourceConfig",
15
+ "OntologyConfig",
16
+ ]