pycityagent 2.0.0a13__py3-none-any.whl → 2.0.0a14__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.
@@ -0,0 +1,120 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import List, Dict, Optional
3
+ from datetime import datetime
4
+ from enum import Enum
5
+ import uuid
6
+ import json
7
+
8
+
9
+ class QuestionType(Enum):
10
+ TEXT = "text"
11
+ RADIO = "radiogroup"
12
+ CHECKBOX = "checkbox"
13
+ BOOLEAN = "boolean"
14
+ RATING = "rating"
15
+ MATRIX = "matrix"
16
+
17
+
18
+ @dataclass
19
+ class Question:
20
+ name: str
21
+ title: str
22
+ type: QuestionType
23
+ choices: List[str] = field(default_factory=list)
24
+ columns: List[str] = field(default_factory=list)
25
+ rows: List[str] = field(default_factory=list)
26
+ min_rating: int = 1
27
+ max_rating: int = 5
28
+
29
+ def to_dict(self) -> dict:
30
+ base_dict = {
31
+ "type": self.type.value,
32
+ "name": self.name,
33
+ "title": self.title,
34
+ }
35
+
36
+ if self.type in [QuestionType.RADIO, QuestionType.CHECKBOX]:
37
+ base_dict["choices"] = self.choices
38
+ elif self.type == QuestionType.MATRIX:
39
+ base_dict["columns"] = self.columns
40
+ base_dict["rows"] = self.rows
41
+ elif self.type == QuestionType.RATING:
42
+ base_dict["min_rating"] = self.min_rating
43
+ base_dict["max_rating"] = self.max_rating
44
+
45
+ return base_dict
46
+
47
+
48
+ @dataclass
49
+ class Page:
50
+ name: str
51
+ elements: List[Question]
52
+
53
+ def to_dict(self) -> dict:
54
+ return {
55
+ "name": self.name,
56
+ "elements": [q.to_dict() for q in self.elements]
57
+ }
58
+
59
+
60
+ @dataclass
61
+ class Survey:
62
+ id: uuid.UUID
63
+ title: str
64
+ description: str
65
+ pages: List[Page]
66
+ responses: Dict[str, dict] = field(default_factory=dict)
67
+ created_at: datetime = field(default_factory=datetime.now)
68
+
69
+ def to_dict(self) -> dict:
70
+ return {
71
+ "id": str(self.id),
72
+ "title": self.title,
73
+ "description": self.description,
74
+ "pages": [p.to_dict() for p in self.pages],
75
+ "response_count": len(self.responses),
76
+ }
77
+
78
+ def to_json(self) -> str:
79
+ """Convert the survey to a JSON string for MQTT transmission"""
80
+ survey_dict = {
81
+ "id": str(self.id),
82
+ "title": self.title,
83
+ "description": self.description,
84
+ "pages": [p.to_dict() for p in self.pages],
85
+ "responses": self.responses,
86
+ "created_at": self.created_at.isoformat()
87
+ }
88
+ return json.dumps(survey_dict)
89
+
90
+ @classmethod
91
+ def from_json(cls, json_str: str) -> 'Survey':
92
+ """Create a Survey instance from a JSON string"""
93
+ data = json.loads(json_str)
94
+ pages = [
95
+ Page(
96
+ name=p["name"],
97
+ elements=[
98
+ Question(
99
+ name=q["name"],
100
+ title=q["title"],
101
+ type=QuestionType(q["type"]),
102
+ required=q.get("required", True),
103
+ choices=q.get("choices", []),
104
+ columns=q.get("columns", []),
105
+ rows=q.get("rows", []),
106
+ min_rating=q.get("min_rating", 1),
107
+ max_rating=q.get("max_rating", 5)
108
+ ) for q in p["elements"]
109
+ ]
110
+ ) for p in data["pages"]
111
+ ]
112
+
113
+ return cls(
114
+ id=uuid.UUID(data["id"]),
115
+ title=data["title"],
116
+ description=data["description"],
117
+ pages=pages,
118
+ responses=data.get("responses", {}),
119
+ created_at=datetime.fromisoformat(data["created_at"])
120
+ )
@@ -0,0 +1,7 @@
1
+ from .avro_schema import PROFILE_SCHEMA, DIALOG_SCHEMA, STATUS_SCHEMA, SURVEY_SCHEMA
2
+ from .survey_util import process_survey_for_llm
3
+
4
+ __all__ = [
5
+ "PROFILE_SCHEMA", "DIALOG_SCHEMA", "STATUS_SCHEMA", "SURVEY_SCHEMA",
6
+ "process_survey_for_llm"
7
+ ]
@@ -0,0 +1,85 @@
1
+ PROFILE_SCHEMA = {
2
+ "doc": "Agent属性",
3
+ "name": "AgentProfile",
4
+ "namespace": "com.socialcity",
5
+ "type": "record",
6
+ "fields": [
7
+ {"name": "id", "type": "string"}, # uuid as string
8
+ {"name": "name", "type": "string"},
9
+ {"name": "gender", "type": "string"},
10
+ {"name": "age", "type": "float"},
11
+ {"name": "education", "type": "string"},
12
+ {"name": "skill", "type": "string"},
13
+ {"name": "occupation", "type": "string"},
14
+ {"name": "family_consumption", "type": "string"},
15
+ {"name": "consumption", "type": "string"},
16
+ {"name": "personality", "type": "string"},
17
+ {"name": "income", "type": "string"},
18
+ {"name": "currency", "type": "float"},
19
+ {"name": "residence", "type": "string"},
20
+ {"name": "race", "type": "string"},
21
+ {"name": "religion", "type": "string"},
22
+ {"name": "marital_status", "type": "string"},
23
+ ],
24
+ }
25
+
26
+ DIALOG_SCHEMA = {
27
+ "doc": "Agent对话",
28
+ "name": "AgentDialog",
29
+ "namespace": "com.socialcity",
30
+ "type": "record",
31
+ "fields": [
32
+ {"name": "id", "type": "string"}, # uuid as string
33
+ {"name": "day", "type": "int"},
34
+ {"name": "t", "type": "float"},
35
+ {"name": "type", "type": "int"},
36
+ {"name": "speaker", "type": "string"},
37
+ {"name": "content", "type": "string"},
38
+ {
39
+ "name": "created_at",
40
+ "type": {"type": "long", "logicalType": "timestamp-millis"},
41
+ },
42
+ ],
43
+ }
44
+
45
+ STATUS_SCHEMA = {
46
+ "doc": "Agent状态",
47
+ "name": "AgentStatus",
48
+ "namespace": "com.socialcity",
49
+ "type": "record",
50
+ "fields": [
51
+ {"name": "id", "type": "string"}, # uuid as string
52
+ {"name": "day", "type": "int"},
53
+ {"name": "t", "type": "float"},
54
+ {"name": "lng", "type": "double"},
55
+ {"name": "lat", "type": "double"},
56
+ {"name": "parent_id", "type": "int"},
57
+ {"name": "action", "type": "string"},
58
+ {"name": "hungry", "type": "float"},
59
+ {"name": "tired", "type": "float"},
60
+ {"name": "safe", "type": "float"},
61
+ {"name": "social", "type": "float"},
62
+ {
63
+ "name": "created_at",
64
+ "type": {"type": "long", "logicalType": "timestamp-millis"},
65
+ },
66
+ ],
67
+ }
68
+
69
+ SURVEY_SCHEMA = {
70
+ "doc": "Agent问卷",
71
+ "name": "AgentSurvey",
72
+ "namespace": "com.socialcity",
73
+ "type": "record",
74
+ "fields": [
75
+ {"name": "id", "type": "string"}, # uuid as string
76
+ {"name": "day", "type": "int"},
77
+ {"name": "t", "type": "float"},
78
+ {"name": "survey_id", "type": "string"},
79
+ {"name": "result", "type": "string"},
80
+ {
81
+ "name": "created_at",
82
+ "type": {"type": "long", "logicalType": "timestamp-millis"},
83
+ },
84
+ ],
85
+ }
@@ -0,0 +1,53 @@
1
+ def process_survey_for_llm(survey_dict: dict) -> str:
2
+ """
3
+ 将问卷字典转换为LLM可以逐题处理的格式,使用英文提示
4
+ """
5
+ prompt = f"""Survey Title: {survey_dict['title']}
6
+ Survey Description: {survey_dict['description']}
7
+
8
+ Please answer each question in the following format:
9
+
10
+ """
11
+
12
+ question_count = 1
13
+ for page in survey_dict['pages']:
14
+ for question in page['elements']:
15
+ prompt += f"Question {question_count}: {question['title']}\n"
16
+
17
+ # 根据不同类型的问题生成不同的提示
18
+ if question['type'] == 'radiogroup':
19
+ prompt += "Options: " + ", ".join(question['choices']) + "\n"
20
+ prompt += "Please select ONE option\n"
21
+
22
+ elif question['type'] == 'checkbox':
23
+ prompt += "Options: " + ", ".join(question['choices']) + "\n"
24
+ prompt += "You can select MULTIPLE options\n"
25
+
26
+ elif question['type'] == 'rating':
27
+ prompt += f"Rating range: {question.get('min_rating', 1)} - {question.get('max_rating', 5)}\n"
28
+ prompt += "Please provide a rating within the range\n"
29
+
30
+ elif question['type'] == 'matrix':
31
+ prompt += "Rows: " + ", ".join(question['rows']) + "\n"
32
+ prompt += "Columns: " + ", ".join(question['columns']) + "\n"
33
+ prompt += "Please select ONE column option for EACH row\n"
34
+
35
+ elif question['type'] == 'text':
36
+ prompt += "Please provide a text response\n"
37
+
38
+ elif question['type'] == 'boolean':
39
+ prompt += "Options: Yes, No\n"
40
+ prompt += "Please select either Yes or No\n"
41
+
42
+ prompt += "\nAnswer: [Your response here]\n\n---\n\n"
43
+ question_count += 1
44
+
45
+ # 添加总结提示
46
+ prompt += """Please ensure:
47
+ 1. All required questions are answered
48
+ 2. Responses match the question type requirements
49
+ 3. Answers are clear and specific
50
+
51
+ Format your responses exactly as requested above."""
52
+
53
+ return prompt
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycityagent
3
- Version: 2.0.0a13
3
+ Version: 2.0.0a14
4
4
  Summary: LLM-based城市环境agent构建库
5
5
  License: MIT
6
6
  Author: Yuwei Yan
@@ -20,6 +20,7 @@ Requires-Dist: aiohttp (==3.10.10)
20
20
  Requires-Dist: aiomqtt (>=2.3.0,<3.0.0)
21
21
  Requires-Dist: citystreetview (==1.2.4)
22
22
  Requires-Dist: dashscope (==1.14.1)
23
+ Requires-Dist: fastavro (>=1.10.0,<2.0.0)
23
24
  Requires-Dist: geojson (==3.1.0)
24
25
  Requires-Dist: gradio (>=5.7.1,<6.0.0)
25
26
  Requires-Dist: grpcio (==1.67.1)
@@ -28,6 +29,7 @@ Requires-Dist: mosstool (==1.0.24)
28
29
  Requires-Dist: networkx (==3.2.1)
29
30
  Requires-Dist: numpy (>=1.20.0,<2.0.0)
30
31
  Requires-Dist: openai (>=1.58.1,<2.0.0)
32
+ Requires-Dist: pandavro (>=1.8.0,<2.0.0)
31
33
  Requires-Dist: poetry (>=1.2.2)
32
34
  Requires-Dist: protobuf (<=4.24.0)
33
35
  Requires-Dist: pycitydata (==1.0.0)
@@ -1,7 +1,7 @@
1
1
  pycityagent/__init__.py,sha256=n56bWkAUEcvjDsb7LcJpaGjlrriSKPnR0yBhwRfEYBA,212
2
- pycityagent/agent.py,sha256=7BCHK5OH1TvW16JLiYR0iWAiWGBuP4eJsiGU1y7exbY,18417
2
+ pycityagent/agent.py,sha256=0ZqHXImR05ETA0vt9t5GDS4AgYzza3-Zwuua2OckwTw,22788
3
3
  pycityagent/economy/__init__.py,sha256=aonY4WHnx-6EGJ4WKrx4S-2jAkYNLtqUA04jp6q8B7w,75
4
- pycityagent/economy/econ_client.py,sha256=qQb_kZneEXGBRaS_y5Jdoi95I8GyjKEsDSC4s6V6R7w,10829
4
+ pycityagent/economy/econ_client.py,sha256=wcuNtcpkSijJwNkt2mXw3SshYy4SBy6qbvJ0VQ7Aovo,10854
5
5
  pycityagent/environment/__init__.py,sha256=awHxlOud-btWbk0FCS4RmGJ13W84oVCkbGfcrhKqihA,240
6
6
  pycityagent/environment/interact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  pycityagent/environment/interact/interact.py,sha256=ifxPPzuHeqLHIZ_6zvfXMoBOnBsXNIP4bYp7OJ7pnEQ,6588
@@ -36,7 +36,7 @@ pycityagent/llm/llm.py,sha256=BtxBvPK4tb8QlZIfxO5XJ73lKXwF8L31LqVbejWB8eo,15121
36
36
  pycityagent/llm/llmconfig.py,sha256=4Ylf4OFSBEFy8jrOneeX0HvPhWEaF5jGvy1HkXK08Ro,436
37
37
  pycityagent/llm/utils.py,sha256=hoNPhvomb1u6lhFX0GctFipw74hVKb7bvUBDqwBzBYw,160
38
38
  pycityagent/memory/__init__.py,sha256=Hs2NhYpIG-lvpwPWwj4DydB1sxtjz7cuA4iDAzCXnjI,243
39
- pycityagent/memory/const.py,sha256=m9AidLs7Zu28StpvYetclqx-1qQcy3bYvwagcXB3a04,913
39
+ pycityagent/memory/const.py,sha256=6zpJPJXWoH9-yf4RARYYff586agCoud9BRn7sPERB1g,932
40
40
  pycityagent/memory/memory.py,sha256=sDbaqr1Koqf_9joMtG9PmmVxJZ6Rq7nAZO6EO0OdVgo,18148
41
41
  pycityagent/memory/memory_base.py,sha256=bd2q0qNu5hCRd2u4cPxE3bBA2OaoAD1oR4-vbRdbd_s,5594
42
42
  pycityagent/memory/profile.py,sha256=s4LnxSPGSjIGZXHXkkd8mMa6uYYZrytgyQdWjcaqGf4,5182
@@ -46,25 +46,24 @@ pycityagent/memory/utils.py,sha256=wLNlNlZ-AY9VB8kbUIy0UQSYh26FOQABbhmKQkit5o8,8
46
46
  pycityagent/message/__init__.py,sha256=TCjazxqb5DVwbTu1fF0sNvaH_EPXVuj2XQ0p6W-QCLU,55
47
47
  pycityagent/message/messager.py,sha256=Iv4pK83JvHAQSZyGNACryPBey2wRoiok3Hb1eIwHbww,2506
48
48
  pycityagent/simulation/__init__.py,sha256=jYaqaNpzM5M_e_ykISS_M-mIyYdzJXJWhgpfBpA6l5k,111
49
- pycityagent/simulation/agentgroup.py,sha256=fM93ydsuZ_w8YVnHnX1tWskWVYmt6sztKjzgDXcg1Xw,6106
50
- pycityagent/simulation/interview.py,sha256=S2uv8MFCB4-u_4Q202VFoPJOIleqpKK9Piju0BDSb_0,1158
51
- pycityagent/simulation/simulation.py,sha256=4BHavfSHPM81Y5Su-MzzBYM0sR9cHRk4YOv-VkRkzrA,11595
52
- pycityagent/simulation/survey/__init__.py,sha256=rxwou8U9KeFSP7rMzXtmtp2fVFZxK4Trzi-psx9LPIs,153
53
- pycityagent/simulation/survey/manager.py,sha256=Tqini-4-uBZDsChVVL4ezlgXatnrxAfvceAZZRP8E48,2062
54
- pycityagent/simulation/survey/models.py,sha256=sY4OrrG1h9iBnjBsyDage4T3mUFPBHHZQe-ORtwSjKc,1305
55
- pycityagent/simulation/ui/__init__.py,sha256=4aevYl09KSku2NEpFZhyFNxI1qlswbrAFwhF_YhxFTo,62
56
- pycityagent/simulation/ui/interface.py,sha256=cSQRQhuA5Gj-X7anuN9tmRpG6-I8QYOuswjIWUeSvio,21636
57
- pycityagent/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
+ pycityagent/simulation/agentgroup.py,sha256=ZJIeQbFmFwK3iUiwUpa4TG-k1Eb4vOTgy5ybv-CE1Rc,7797
50
+ pycityagent/simulation/simulation.py,sha256=rDQRgKmJkjfeQtvXyW9LeqBVVX0iFh6snBEsdg1bCag,15574
51
+ pycityagent/survey/__init__.py,sha256=rxwou8U9KeFSP7rMzXtmtp2fVFZxK4Trzi-psx9LPIs,153
52
+ pycityagent/survey/manager.py,sha256=N4-Q8vve4L-PLaFikAgVB4Z8BNyFDEd6WjEk3AyMTgs,1764
53
+ pycityagent/survey/models.py,sha256=Z2gHEazQRj0TkTz5qbh4Uy_JrU_FZGWpOLwjN0RoUrY,3547
54
+ pycityagent/utils/__init__.py,sha256=_0AV01UAHp4pTj2mlJ4m8LTH0toWL9j3DouNC6sDuUQ,249
55
+ pycityagent/utils/avro_schema.py,sha256=MsRG0CsYAn2UjSlSXgCF8-3076VywpALEmz1mW-UJB0,2789
58
56
  pycityagent/utils/decorators.py,sha256=Gk3r41hfk6awui40tbwpq3C7wC7jHaRmLRlcJFlLQCE,3160
59
57
  pycityagent/utils/parsers/__init__.py,sha256=AN2xgiPxszWK4rpX7zrqRsqNwfGF3WnCA5-PFTvbaKk,281
60
58
  pycityagent/utils/parsers/code_block_parser.py,sha256=Cs2Z_hm9VfNCpPPll1TwteaJF-HAQPs-3RApsOekFm4,1173
61
59
  pycityagent/utils/parsers/json_parser.py,sha256=FZ3XN1g8z4Dr2TFraUOoah1oQcze4fPd2m01hHoX0Mo,2917
62
60
  pycityagent/utils/parsers/parser_base.py,sha256=k6DVqwAMK3jJdOP4IeLE-aFPm3V2F-St5qRBuRdx4aU,1742
61
+ pycityagent/utils/survey_util.py,sha256=Be9nptmu2JtesFNemPgORh_2GsN7rcDYGQS9Zfvc5OI,2169
63
62
  pycityagent/workflow/__init__.py,sha256=EyCcjB6LyBim-5iAOPe4m2qfvghEPqu1ZdGfy4KPeZ8,551
64
63
  pycityagent/workflow/block.py,sha256=6EmiRMLdOZC1wMlmLMIjfrp9TuiI7Gw4s3nnXVMbrnw,6031
65
64
  pycityagent/workflow/prompt.py,sha256=tY69nDO8fgYfF_dOA-iceR8pAhkYmCqoox8uRPqEuGY,2956
66
65
  pycityagent/workflow/tool.py,sha256=wD9WZ5rma6HCKugtHTwbShNE0f-Rjlwvn_1be3fCAsk,6682
67
66
  pycityagent/workflow/trigger.py,sha256=t5X_i0WtL32bipZSsq_E3UUyYYudYLxQUpvxbgClp2s,5683
68
- pycityagent-2.0.0a13.dist-info/METADATA,sha256=MdIVm_sOeGM99wtIKpcDEt6zt3Gp-loHI5MxGTz_6og,7622
69
- pycityagent-2.0.0a13.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
70
- pycityagent-2.0.0a13.dist-info/RECORD,,
67
+ pycityagent-2.0.0a14.dist-info/METADATA,sha256=O6cGdAHKuG6W0Ya_Du_wEP8_xfM4xmOetYWb6rPj-WM,7705
68
+ pycityagent-2.0.0a14.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
69
+ pycityagent-2.0.0a14.dist-info/RECORD,,
@@ -1,40 +0,0 @@
1
- from dataclasses import dataclass
2
- from datetime import datetime
3
- from typing import List, Optional
4
-
5
-
6
- @dataclass
7
- class InterviewRecord:
8
- """采访记录"""
9
-
10
- timestamp: datetime
11
- agent_name: str
12
- question: str
13
- response: str
14
- blocking: bool
15
-
16
-
17
- class InterviewManager:
18
- """采访管理器"""
19
-
20
- def __init__(self):
21
- self._history: List[InterviewRecord] = []
22
-
23
- def add_record(self, agent_name: str, question: str, response: str, blocking: bool):
24
- """添加采访记录"""
25
- record = InterviewRecord(
26
- timestamp=datetime.now(),
27
- agent_name=agent_name,
28
- question=question,
29
- response=response,
30
- blocking=blocking,
31
- )
32
- self._history.append(record)
33
-
34
- def get_agent_history(self, agent_name: str) -> List[InterviewRecord]:
35
- """获取指定智能体的采访历史"""
36
- return [r for r in self._history if r.agent_name == agent_name]
37
-
38
- def get_recent_history(self, limit: int = 10) -> List[InterviewRecord]:
39
- """获取最近的采访记录"""
40
- return sorted(self._history, key=lambda x: x.timestamp, reverse=True)[:limit]
@@ -1,68 +0,0 @@
1
- from typing import List, Dict, Optional
2
- from datetime import datetime
3
- import uuid
4
- import json
5
- from .models import Survey, Question, QuestionType
6
-
7
-
8
- class SurveyManager:
9
- def __init__(self):
10
- self._surveys: Dict[str, Survey] = {}
11
-
12
- def create_survey(
13
- self, title: str, description: str, questions: List[dict]
14
- ) -> Survey:
15
- """创建新问卷"""
16
- survey_id = str(uuid.uuid4())
17
-
18
- # 转换问题数据
19
- survey_questions = []
20
- for q in questions:
21
- question = Question(
22
- content=q["content"],
23
- type=QuestionType(q["type"]),
24
- required=q.get("required", True),
25
- options=q.get("options", []),
26
- min_rating=q.get("min_rating", 1),
27
- max_rating=q.get("max_rating", 5),
28
- )
29
- survey_questions.append(question)
30
-
31
- survey = Survey(
32
- id=survey_id,
33
- title=title,
34
- description=description,
35
- questions=survey_questions,
36
- )
37
-
38
- self._surveys[survey_id] = survey
39
- return survey
40
-
41
- def get_survey(self, survey_id: str) -> Optional[Survey]:
42
- """获取指定问卷"""
43
- return self._surveys.get(survey_id)
44
-
45
- def get_all_surveys(self) -> List[Survey]:
46
- """获取所有问卷"""
47
- return list(self._surveys.values())
48
-
49
- def add_response(self, survey_id: str, agent_name: str, response: dict) -> bool:
50
- """添加问卷回答"""
51
- survey = self.get_survey(survey_id)
52
- if not survey:
53
- return False
54
-
55
- survey.responses[agent_name] = {"timestamp": datetime.now(), **response}
56
- return True
57
-
58
- def export_results(self, survey_id: str) -> str:
59
- """导出问卷结果"""
60
- survey = self.get_survey(survey_id)
61
- if not survey:
62
- return json.dumps({"error": "问卷不存在"})
63
-
64
- return json.dumps(
65
- {"survey": survey.to_dict(), "responses": survey.responses},
66
- ensure_ascii=False,
67
- indent=2,
68
- )
@@ -1,52 +0,0 @@
1
- from dataclasses import dataclass, field
2
- from typing import List, Dict, Optional
3
- from datetime import datetime
4
- from enum import Enum
5
- import uuid
6
-
7
-
8
- class QuestionType(Enum):
9
- TEXT = "文本"
10
- SINGLE_CHOICE = "单选"
11
- MULTIPLE_CHOICE = "多选"
12
- RATING = "评分"
13
- LIKERT = "李克特量表"
14
-
15
-
16
- @dataclass
17
- class Question:
18
- content: str
19
- type: QuestionType
20
- required: bool = True
21
- options: List[str] = field(default_factory=list)
22
- min_rating: int = 1
23
- max_rating: int = 5
24
-
25
- def to_dict(self) -> dict:
26
- return {
27
- "content": self.content,
28
- "type": self.type.value,
29
- "required": self.required,
30
- "options": self.options,
31
- "min_rating": self.min_rating,
32
- "max_rating": self.max_rating,
33
- }
34
-
35
-
36
- @dataclass
37
- class Survey:
38
- id: str
39
- title: str
40
- description: str
41
- questions: List[Question]
42
- responses: Dict[str, dict] = field(default_factory=dict)
43
- created_at: datetime = field(default_factory=datetime.now)
44
-
45
- def to_dict(self) -> dict:
46
- return {
47
- "id": self.id,
48
- "title": self.title,
49
- "description": self.description,
50
- "questions": [q.to_dict() for q in self.questions],
51
- "response_count": len(self.responses),
52
- }
@@ -1,3 +0,0 @@
1
- from .interface import InterviewUI
2
-
3
- __all__ = ["InterviewUI"]