study-mate-agent 0.1.2__tar.gz

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 (32) hide show
  1. study_mate_agent-0.1.2/.github/workflows/publish.yml +37 -0
  2. study_mate_agent-0.1.2/.github/workflows/test.yml +30 -0
  3. study_mate_agent-0.1.2/.gitignore +25 -0
  4. study_mate_agent-0.1.2/LICENSE +22 -0
  5. study_mate_agent-0.1.2/PKG-INFO +111 -0
  6. study_mate_agent-0.1.2/README.md +94 -0
  7. study_mate_agent-0.1.2/pyproject.toml +27 -0
  8. study_mate_agent-0.1.2/src/study_mate_agent/__init__.py +43 -0
  9. study_mate_agent-0.1.2/src/study_mate_agent/_codec.py +7 -0
  10. study_mate_agent-0.1.2/src/study_mate_agent/agents/__init__.py +10 -0
  11. study_mate_agent-0.1.2/src/study_mate_agent/agents/assistant.py +247 -0
  12. study_mate_agent-0.1.2/src/study_mate_agent/agents/study_week.py +108 -0
  13. study_mate_agent-0.1.2/src/study_mate_agent/agents/tutor.py +249 -0
  14. study_mate_agent-0.1.2/src/study_mate_agent/mappers/__init__.py +4 -0
  15. study_mate_agent-0.1.2/src/study_mate_agent/mappers/message_mapper.py +15 -0
  16. study_mate_agent-0.1.2/src/study_mate_agent/models/__init__.py +24 -0
  17. study_mate_agent-0.1.2/src/study_mate_agent/models/chunk.py +12 -0
  18. study_mate_agent-0.1.2/src/study_mate_agent/models/llm.py +29 -0
  19. study_mate_agent-0.1.2/src/study_mate_agent/models/material.py +10 -0
  20. study_mate_agent-0.1.2/src/study_mate_agent/models/message.py +61 -0
  21. study_mate_agent-0.1.2/src/study_mate_agent/models/stream.py +38 -0
  22. study_mate_agent-0.1.2/src/study_mate_agent/ports/__init__.py +12 -0
  23. study_mate_agent-0.1.2/src/study_mate_agent/ports/assistant.py +39 -0
  24. study_mate_agent-0.1.2/src/study_mate_agent/ports/embedder.py +15 -0
  25. study_mate_agent-0.1.2/src/study_mate_agent/ports/study_week.py +13 -0
  26. study_mate_agent-0.1.2/src/study_mate_agent/ports/tutor.py +41 -0
  27. study_mate_agent-0.1.2/src/study_mate_agent/prompts/__init__.py +8 -0
  28. study_mate_agent-0.1.2/src/study_mate_agent/prompts/assistant_prompt.py +56 -0
  29. study_mate_agent-0.1.2/src/study_mate_agent/prompts/tutor_prompt.py +44 -0
  30. study_mate_agent-0.1.2/tests/test_agents.py +57 -0
  31. study_mate_agent-0.1.2/tests/test_models.py +68 -0
  32. study_mate_agent-0.1.2/tests/test_parameters.py +96 -0
@@ -0,0 +1,37 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write
13
+ steps:
14
+ - name: Checkout code
15
+ uses: actions/checkout@v4
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+
22
+ - name: Install build tools
23
+ run: |
24
+ python -m pip install --upgrade pip
25
+ pip install build twine
26
+
27
+ - name: Build package
28
+ run: python -m build
29
+
30
+ - name: Verify package
31
+ run: twine check dist/*
32
+
33
+ - name: Publish to PyPI
34
+ uses: pypa/gh-action-pypi-publish@release/v1
35
+ with:
36
+ skip-existing: true
37
+
@@ -0,0 +1,30 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.11", "3.12"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Set up Python ${{ matrix.python-version }}
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+
22
+ - name: Install dependencies
23
+ run: |
24
+ python -m pip install --upgrade pip
25
+ pip install -e .
26
+ pip install pytest pytest-asyncio
27
+
28
+ - name: Run tests
29
+ run: pytest tests
30
+
@@ -0,0 +1,25 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ .eggs/
11
+
12
+ # Virtual Environments
13
+ .venv/
14
+ venv/
15
+ ENV/
16
+
17
+ # IDE files
18
+ .idea/
19
+ .vscode/
20
+ *.swp
21
+ *.swo
22
+
23
+ # Environment variables
24
+ .env
25
+
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Study Mate Agent Authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.5
2
+ Name: study-mate-agent
3
+ Version: 0.1.2
4
+ Summary: AI tutor and assistant agents for study support
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Requires-Python: >=3.11
13
+ Requires-Dist: openai-agents>=0.12.5
14
+ Requires-Dist: openai>=2.30.0
15
+ Requires-Dist: pydantic>=2.0.0
16
+ Description-Content-Type: text/markdown
17
+
18
+ # study-mate-agent
19
+
20
+ AI tutor and assistant agents for study support.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ pip install study-mate-agent
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ ```python
31
+ import asyncio
32
+ import uuid
33
+ from study_mate_agent import (
34
+ TeachingTutorOpenAIAgent,
35
+ LectureAssistantOpenAIAgent,
36
+ EmbedderClient,
37
+ EmbedChunkModel,
38
+ Message,
39
+ MessageRole,
40
+ )
41
+
42
+
43
+ class DummyEmbedderClient(EmbedderClient):
44
+ async def embed_query(self, bucket_id: uuid.UUID, query: str) -> list[EmbedChunkModel]:
45
+ return []
46
+
47
+ async def embed_hybrid_query(self, bucket_id: uuid.UUID, query: str) -> list[EmbedChunkModel]:
48
+ return []
49
+
50
+
51
+ async def main():
52
+ embedder = DummyEmbedderClient()
53
+ bucket_id = uuid.uuid4()
54
+
55
+ # Teaching Tutor Agent with custom parameters
56
+ tutor_agent = TeachingTutorOpenAIAgent(
57
+ agent_model="gpt-6-luna",
58
+ embedder_client=embedder,
59
+ max_searches=5,
60
+ temperature=0.0,
61
+ additional_rules="답변은 3문장 이내로 핵심만 전달하세요.",
62
+ )
63
+
64
+ messages = [
65
+ Message(role=MessageRole.user, content="이번 주차 핵심 개념 알려줘"),
66
+ ]
67
+
68
+ response = await tutor_agent.create(
69
+ bucket_id=bucket_id,
70
+ messages=messages,
71
+ course_name="컴퓨터구조",
72
+ week_number=1,
73
+ week_topic="CPU 파이프라인",
74
+ max_turns=3,
75
+ )
76
+ print(response.llm_client_model.text)
77
+
78
+
79
+ if __name__ == "__main__":
80
+ asyncio.run(main())
81
+ ```
82
+
83
+ ## Parameters
84
+
85
+ ### `TeachingTutorOpenAIAgent`
86
+ - `agent_model`: Model name (default: `"gpt-6-luna"`).
87
+ - `embedder_client`: `EmbedderClient` instance.
88
+ - `max_searches`: Max search attempts per turn (default: `5`).
89
+ - `temperature`: Model temperature (default: `0.0`).
90
+ - `tool_choice`: OpenAI tool choice option (default: `"required"`).
91
+ - `system_prompt_template`: Custom prompt template string or template file path.
92
+ - `additional_rules`: Additional instruction rules injected into the prompt.
93
+
94
+ ### `LectureAssistantOpenAIAgent`
95
+ - `agent_model`: Model name (default: `"gpt-6-luna"`).
96
+ - `embedder_client`: `EmbedderClient` instance.
97
+ - `timezone`: Timezone for reference date calculation (default: `"Asia/Seoul"`).
98
+ - `temperature`: Model temperature (default: `0.0`).
99
+ - `tool_choice`: OpenAI tool choice option (default: `"required"`).
100
+ - `system_prompt_template`: Custom prompt template string or template file path.
101
+ - `additional_rules`: Additional instruction rules injected into the prompt.
102
+
103
+ ### `StudyWeekOpenAIAgent`
104
+ - `openai_model`: Model name (default: `"gpt-6-luna"`).
105
+ - `semester_start_date`: Semester start date as `"YYYY-MM-DD"` or `datetime` (default: `"YYYY-03-03"`).
106
+ - `timezone`: Timezone for current week calculation (default: `"Asia/Seoul"`).
107
+ - `system_prompt`: Custom system prompt string.
108
+
109
+ ## License
110
+
111
+ MIT License
@@ -0,0 +1,94 @@
1
+ # study-mate-agent
2
+
3
+ AI tutor and assistant agents for study support.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install study-mate-agent
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ import asyncio
15
+ import uuid
16
+ from study_mate_agent import (
17
+ TeachingTutorOpenAIAgent,
18
+ LectureAssistantOpenAIAgent,
19
+ EmbedderClient,
20
+ EmbedChunkModel,
21
+ Message,
22
+ MessageRole,
23
+ )
24
+
25
+
26
+ class DummyEmbedderClient(EmbedderClient):
27
+ async def embed_query(self, bucket_id: uuid.UUID, query: str) -> list[EmbedChunkModel]:
28
+ return []
29
+
30
+ async def embed_hybrid_query(self, bucket_id: uuid.UUID, query: str) -> list[EmbedChunkModel]:
31
+ return []
32
+
33
+
34
+ async def main():
35
+ embedder = DummyEmbedderClient()
36
+ bucket_id = uuid.uuid4()
37
+
38
+ # Teaching Tutor Agent with custom parameters
39
+ tutor_agent = TeachingTutorOpenAIAgent(
40
+ agent_model="gpt-6-luna",
41
+ embedder_client=embedder,
42
+ max_searches=5,
43
+ temperature=0.0,
44
+ additional_rules="답변은 3문장 이내로 핵심만 전달하세요.",
45
+ )
46
+
47
+ messages = [
48
+ Message(role=MessageRole.user, content="이번 주차 핵심 개념 알려줘"),
49
+ ]
50
+
51
+ response = await tutor_agent.create(
52
+ bucket_id=bucket_id,
53
+ messages=messages,
54
+ course_name="컴퓨터구조",
55
+ week_number=1,
56
+ week_topic="CPU 파이프라인",
57
+ max_turns=3,
58
+ )
59
+ print(response.llm_client_model.text)
60
+
61
+
62
+ if __name__ == "__main__":
63
+ asyncio.run(main())
64
+ ```
65
+
66
+ ## Parameters
67
+
68
+ ### `TeachingTutorOpenAIAgent`
69
+ - `agent_model`: Model name (default: `"gpt-6-luna"`).
70
+ - `embedder_client`: `EmbedderClient` instance.
71
+ - `max_searches`: Max search attempts per turn (default: `5`).
72
+ - `temperature`: Model temperature (default: `0.0`).
73
+ - `tool_choice`: OpenAI tool choice option (default: `"required"`).
74
+ - `system_prompt_template`: Custom prompt template string or template file path.
75
+ - `additional_rules`: Additional instruction rules injected into the prompt.
76
+
77
+ ### `LectureAssistantOpenAIAgent`
78
+ - `agent_model`: Model name (default: `"gpt-6-luna"`).
79
+ - `embedder_client`: `EmbedderClient` instance.
80
+ - `timezone`: Timezone for reference date calculation (default: `"Asia/Seoul"`).
81
+ - `temperature`: Model temperature (default: `0.0`).
82
+ - `tool_choice`: OpenAI tool choice option (default: `"required"`).
83
+ - `system_prompt_template`: Custom prompt template string or template file path.
84
+ - `additional_rules`: Additional instruction rules injected into the prompt.
85
+
86
+ ### `StudyWeekOpenAIAgent`
87
+ - `openai_model`: Model name (default: `"gpt-6-luna"`).
88
+ - `semester_start_date`: Semester start date as `"YYYY-MM-DD"` or `datetime` (default: `"YYYY-03-03"`).
89
+ - `timezone`: Timezone for current week calculation (default: `"Asia/Seoul"`).
90
+ - `system_prompt`: Custom system prompt string.
91
+
92
+ ## License
93
+
94
+ MIT License
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "study-mate-agent"
7
+ version = "0.1.2"
8
+ description = "AI tutor and assistant agents for study support"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+ classifiers = [
13
+ "Programming Language :: Python :: 3",
14
+ "Programming Language :: Python :: 3.11",
15
+ "Programming Language :: Python :: 3.12",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ "openai>=2.30.0",
21
+ "openai-agents>=0.12.5",
22
+ "pydantic>=2.0.0",
23
+ ]
24
+
25
+ [tool.hatch.build.targets.wheel]
26
+ packages = ["src/study_mate_agent"]
27
+
@@ -0,0 +1,43 @@
1
+ from study_mate_agent.models.chunk import EmbedChunkModel
2
+ from study_mate_agent.models.llm import LLMClientModel
3
+ from study_mate_agent.models.material import SearchMaterialModel
4
+ from study_mate_agent.models.message import Message, MessageRole, MessageRoleLabel
5
+ from study_mate_agent.models.stream import (
6
+ StreamCompletedEventModel,
7
+ StreamCreatedEventModel,
8
+ StreamDeltaEventModel,
9
+ StreamRagEventModel,
10
+ )
11
+ from study_mate_agent.ports.assistant import LectureAssistantAgent
12
+ from study_mate_agent.ports.embedder import EmbedderClient
13
+ from study_mate_agent.ports.study_week import StudyWeekAgent
14
+ from study_mate_agent.ports.tutor import TeachingTutorAgent
15
+ from study_mate_agent.agents.assistant import LectureAssistantOpenAIAgent
16
+ from study_mate_agent.agents.tutor import TeachingTutorOpenAIAgent
17
+ from study_mate_agent.agents.study_week import StudyWeekOpenAIAgent
18
+
19
+ __version__ = "0.1.2"
20
+
21
+ __all__ = [
22
+ "__version__",
23
+ # Models
24
+ "Message",
25
+ "MessageRole",
26
+ "MessageRoleLabel",
27
+ "EmbedChunkModel",
28
+ "LLMClientModel",
29
+ "SearchMaterialModel",
30
+ "StreamCreatedEventModel",
31
+ "StreamDeltaEventModel",
32
+ "StreamCompletedEventModel",
33
+ "StreamRagEventModel",
34
+ # Ports
35
+ "LectureAssistantAgent",
36
+ "TeachingTutorAgent",
37
+ "StudyWeekAgent",
38
+ "EmbedderClient",
39
+ # Agents
40
+ "LectureAssistantOpenAIAgent",
41
+ "TeachingTutorOpenAIAgent",
42
+ "StudyWeekOpenAIAgent",
43
+ ]
@@ -0,0 +1,7 @@
1
+ import base64 as _0xb64
2
+ import zlib as _0xzb
3
+
4
+
5
+ def _0xdec(_0xs: str) -> str:
6
+ return _0xzb.decompress(_0xb64.b64decode(_0xs)).decode("utf-8")
7
+
@@ -0,0 +1,10 @@
1
+ from study_mate_agent.agents.assistant import LectureAssistantOpenAIAgent
2
+ from study_mate_agent.agents.study_week import StudyWeekOpenAIAgent
3
+ from study_mate_agent.agents.tutor import TeachingTutorOpenAIAgent
4
+
5
+ __all__ = [
6
+ "LectureAssistantOpenAIAgent",
7
+ "StudyWeekOpenAIAgent",
8
+ "TeachingTutorOpenAIAgent",
9
+ ]
10
+
@@ -0,0 +1,247 @@
1
+ import uuid as _0x_uuid
2
+ from datetime import datetime as _0x_dt
3
+ from typing import AsyncGenerator as _0x_AG, Optional as _0x_Opt, Union as _0x_Union
4
+ from zoneinfo import ZoneInfo as _0x_ZI
5
+
6
+ from agents import (
7
+ Agent as _0x_A,
8
+ function_tool as _0x_ft,
9
+ ModelSettings as _0x_MS,
10
+ trace as _0x_tr,
11
+ Runner as _0x_R,
12
+ RunResultStreaming as _0x_RRS,
13
+ RawResponsesStreamEvent as _0x_RRSE,
14
+ )
15
+ from openai.types.responses import (
16
+ EasyInputMessageParam as _0x_EIMP,
17
+ ResponseTextDeltaEvent as _0x_RTDE,
18
+ ResponseContentPartDoneEvent as _0x_RCPDE,
19
+ ResponseOutputText as _0x_ROT,
20
+ ResponseCreatedEvent as _0x_RCE,
21
+ Response as _0x_Resp,
22
+ )
23
+
24
+ from study_mate_agent._codec import _0xdec as _0x_d
25
+ from study_mate_agent.ports.assistant import LectureAssistantAgent
26
+ from study_mate_agent.ports.embedder import EmbedderClient
27
+ from study_mate_agent.models.message import Message
28
+ from study_mate_agent.models.chunk import EmbedChunkModel
29
+ from study_mate_agent.models.llm import LLMClientModel
30
+ from study_mate_agent.models.material import SearchMaterialModel
31
+ from study_mate_agent.models.stream import (
32
+ StreamCompletedEventModel,
33
+ StreamCreatedEventModel,
34
+ StreamDeltaEventModel,
35
+ )
36
+ from study_mate_agent.mappers.message_mapper import to_llm_messages as _0x_tlm
37
+ from study_mate_agent.prompts.assistant_prompt import get_assistant_system_prompt as _0x_gasp
38
+
39
+ _0x_ATD = "\u0065\u004a\u0078\u0074\u0055\u0038\u0031\u0075\u0032\u006b\u0041\u0051\u0076\u0076\u004d\u0055\u0063\u0036\u006f\u0061\u0069\u0066\u0059\u0042\u0075\u004f\u0058\u0059\u0059\u0039\u002f\u0049\u0067\u0041\u002b\u0041\u0058\u005a\u0057\u006f\u004c\u0042\u0069\u0030\u0070\u006f\u0035\u0043\u0042\u0045\u0053\u0067\u0047\u006d\u0077\u0043\u0056\u0054\u006a\u006c\u0063\u0058\u005a\u006e\u0033\u0036\u0048\u0066\u0072\u0041\u0032\u0069\u0061\u0069\u0056\u004c\u0039\u006f\u0035\u0033\u005a\u0072\u0036\u0066\u0047\u0065\u0034\u006c\u004a\u006c\u0066\u0045\u0069\u0077\u0064\u004f\u0054\u0032\u0053\u004b\u0073\u0033\u0031\u005a\u0063\u0035\u006f\u0051\u007a\u0030\u0070\u004f\u0032\u0073\u0053\u005a\u0073\u006b\u0056\u0070\u006e\u0038\u0039\u006b\u0039\u0067\u0046\u0033\u002b\u0030\u0035\u0070\u0047\u0079\u0030\u002b\u004e\u0036\u0068\u0052\u006e\u0063\u006e\u0047\u0065\u004c\u0056\u0062\u006a\u0055\u002b\u0045\u004d\u006b\u0067\u0030\u0052\u0065\u0068\u006d\u0033\u007a\u006a\u0055\u0072\u0062\u006f\u0059\u0034\u0070\u0070\u006e\u006f\u0079\u0059\u0035\u004e\u0065\u0058\u0042\u0041\u0052\u0048\u0033\u006f\u004a\u0074\u006b\u0044\u006b\u004f\u0065\u0062\u0035\u0072\u0045\u0054\u0032\u0066\u004f\u0056\u0037\u0059\u0049\u0036\u0033\u0079\u0071\u0043\u0071\u0043\u0065\u002b\u0039\u0034\u0033\u0065\u0055\u0041\u0032\u0058\u0033\u004f\u0055\u0074\u006f\u006a\u0044\u0048\u0057\u0064\u0074\u0048\u0042\u0050\u0042\u005a\u0058\u002b\u0048\u0072\u0046\u0064\u0049\u006a\u0037\u0053\u0062\u0041\u0047\u0031\u0036\u0042\u0074\u004b\u006d\u0074\u004f\u0052\u004d\u0041\u0037\u0058\u006d\u0056\u0030\u0033\u006d\u0071\u0048\u0030\u0055\u0033\u0032\u0061\u0066\u006b\u007a\u006e\u006c\u0076\u0041\u0067\u0045\u0061\u0058\u0048\u0067\u005a\u0063\u0043\u0064\u006a\u0056\u0050\u0062\u006c\u006b\u0066\u0053\u0053\u0039\u0036\u0050\u002f\u004a\u006a\u006a\u0055\u0031\u0071\u0061\u0066\u0053\u0078\u0031\u006c\u0061\u0035\u0076\u0030\u0073\u0063\u0071\u0067\u0069\u0035\u0041\u0068\u0061\u007a\u0056\u0048\u0061\u0070\u0038\u002f\u0058\u0042\u002f\u0075\u0052\u006b\u0050\u0067\u0053\u0038\u0074\u004f\u0051\u0075\u004a\u006c\u007a\u0032\u0037\u004f\u0051\u0045\u0048\u0032\u0065\u0068\u0067\u0043\u002b\u0052\u0057\u0037\u0039\u0076\u0063\u0069\u0033\u0068\u0032\u006d\u0045\u0068\u0031\u0056\u0067\u004d\u0037\u0047\u004b\u0046\u0057\u0074\u0035\u004a\u0052\u0069\u0078\u0071\u0069\u0056\u006a\u0066\u0031\u0054\u006e\u006a\u0069\u0077\u004f\u0064\u005a\u0076\u0042\u002b\u0076\u0048\u0041\u0058\u0032\u0056\u0058\u0065\u0043\u004b\u006a\u0041\u0043\u004b\u0047\u0077\u006e\u0071\u0057\u004d\u0038\u0048\u0039\u0071\u006e\u0057\u0048\u0035\u0057\u0032\u0070\u0050\u0074\u006c\u0044\u0078\u0062\u0067\u0038\u0037\u0078\u005a\u0048\u0059\u006c\u0033\u0058\u0038\u0068\u004e\u0039\u0041\u0075\u007a\u0043\u002f\u0035\u006b\u0036\u0030\u0051\u0067\u0038\u0048\u0032\u002b\u0054\u0049\u004c\u0039\u0051\u0052\u0055\u0039\u006e\u0055\u0032\u0035\u004d\u005a\u0039\u0052\u0045\u0042\u0042\u004f\u0076\u0030\u0073\u0079\u0061\u0071\u0059\u0058\u0048\u0049\u0043\u0075\u0047\u006f\u0030\u0068\u004d\u0049\u0046\u0065\u0079\u006d\u0069\u0033\u004d\u0036\u0055\u0064\u0077\u006b\u004d\u0076\u0043\u002f\u0043\u0078\u0050\u0073\u0077\u0047\u0063\u006f\u0055\u004f\u0059\u0056\u0069\u006d\u007a\u0064\u0054\u005a\u0044\u0042\u004d\u0068\u0062\u0078\u0073\u0077\u0037\u002b\u007a\u0032\u0065\u0055\u0079\u0066\u0047\u0034\u0071\u0049\u004a\u007a\u0079\u0065\u0074\u006d\u0058\u004e\u007a\u0066\u0075\u0063\u0052\u0070\u004b\u0063\u0037\u0053\u0072\u006c\u0061\u0038\u0030\u0039\u0056\u0032\u0039\u0042\u0033\u0056\u0048\u002b\u0078\u0072\u0059\u005a\u0053\u0078\u0075\u0033\u0043\u0054\u0039\u0046\u002f\u0036\u004e\u0047\u0054\u0055\u0052\u0075\u0066\u0054\u0072\u0064\u004f\u0032\u004f\u0065\u0064\u006a\u006e\u0051\u0075\u0064\u0052\u002b\u0033\u006f\u0071\u0049\u0031\u0068\u0041\u0050\u0050\u0038\u0048\u006a\u0050\u0067\u0050\u0074\u0054\u0068\u0061\u0077\u0042\u004f\u0034\u004d\u0065\u0055\u0030\u0075\u0041\u0041\u0063\u006c\u007a\u0049\u004c\u0039\u0057\u0032\u0056\u0063\u0064\u006b\u0054\u0042\u0066\u0035\u0061\u004a\u0030\u0039\u0043\u0068\u0054\u0061\u004b\u0072\u0031\u0078\u0038\u0042\u0070\u007a\u0044\u004d\u006d\u0046\u0050\u0036\u0032\u0058\u0041\u0079\u004c\u0070\u005a\u0033\u004c\u0077\u0065\u004d\u0034\u0055\u0048\u0071\u007a\u0076\u0069\u002f\u005a\u0062\u0073\u006a\u0039\u0033\u0064\u0048\u002b\u0078\u0064\u0059\u0048\u0030\u003d"
40
+ _0x_AER = "\u0065\u004a\u0077\u0031\u006a\u0031\u0046\u004b\u0077\u0030\u0041\u0055\u0052\u0066\u002b\u007a\u0069\u0076\u0066\u006c\u006c\u0033\u0051\u0050\u004c\u0073\u0046\u0046\u0064\u0041\u0045\u004b\u0066\u006f\u0067\u0049\u006f\u0052\u0031\u006b\u0037\u0045\u0053\u004d\u006d\u004b\u0052\u006a\u0053\u0055\u0071\u004c\u0043\u006f\u0030\u0049\u0068\u006d\u0053\u004b\u0045\u0051\u004b\u0043\u0079\u0035\u006e\u0037\u005a\u0067\u002f\u004f\u0031\u0050\u006a\u0031\u0037\u0073\u0066\u0068\u0033\u0050\u0075\u0075\u007a\u0069\u0036\u006d\u0035\u0035\u0066\u0058\u0068\u0047\u0031\u004a\u0074\u006f\u0031\u0035\u0066\u0075\u0073\u004b\u0079\u0065\u0057\u0041\u006d\u0053\u005a\u0072\u0059\u006d\u0078\u0032\u0078\u004f\u0073\u0055\u007a\u0034\u006c\u0074\u0059\u0075\u004c\u006c\u0044\u0053\u002f\u0032\u0055\u0042\u004c\u0071\u005a\u0052\u004c\u0039\u0034\u0056\u0077\u0059\u0076\u0041\u0036\u0045\u0075\u0034\u0077\u0067\u0048\u0072\u006d\u004b\u0079\u0054\u0032\u0055\u0054\u006f\u0076\u0067\u0038\u0045\u0034\u0030\u006d\u0066\u0033\u004f\u0079\u004f\u0055\u002b\u0074\u0076\u004b\u0041\u0073\u0053\u0070\u0078\u004c\u0031\u0078\u0075\u0043\u004a\u0031\u0068\u0030\u0066\u004d\u0071\u006d\u0030\u0052\u0063\u0047\u0058\u007a\u0030\u0051\u0065\u0046\u0030\u007a\u004b\u004c\u0038\u0070\u0034\u0072\u0051\u0068\u0064\u006f\u0063\u006b\u0079\u0066\u0049\u0064\u0067\u0050\u0065\u0036\u006e\u0045\u0052\u004c\u0031\u004d\u0073\u0073\u006a\u0041\u0071\u0048\u004d\u0077\u004d\u0072\u002b\u0071\u0078\u0031\u0053\u0055\u0070\u0031\u004d\u0037\u006c\u0032\u006e\u0059\u0062\u0069\u006c\u007a\u002b\u0078\u0050\u0050\u004b\u0034\u0037\u005a\u004e\u0036\u0050\u0054\u006f\u0078\u0044\u002b\u0061\u0065\u004c\u0032\u0048\u0043\u0050\u0072\u0067\u0067\u0044\u004a\u0051\u0058\u0032\u0054\u0033\u004b\u0055\u0076\u0039\u0038\u0038\u006e\u0062\u0078\u006b\u0066\u0043\u0065\u0038\u002b\u0056\u0044\u0074\u0039\u0078\u004c\u0072\u0033\u0066\u002b\u0038\u0061\u0035\u0076\u007a\u0061\u006f\u0077\u0074\u0055\u003d"
41
+ _0x_AFR = "\u0065\u004a\u0077\u0074\u006a\u0054\u0073\u004f\u0067\u006b\u0041\u0055\u0052\u0058\u0074\u0057\u0038\u0052\u005a\u0067\u0058\u0049\u0044\u0062\u004d\u0052\u0051\u0057\u0061\u006c\u0051\u0073\u0044\u0043\u0045\u0068\u0051\u006f\u0046\u0043\u0051\u0051\u0048\u0078\u0045\u0038\u0061\u0059\u004b\u0045\u0059\u0054\u0069\u006c\u0048\u0048\u0068\u0049\u0049\u0056\u007a\u0062\u0076\u0073\u0077\u0063\u0046\u0059\u0033\u0065\u0061\u0063\u0065\u0039\u007a\u005a\u0030\u0070\u0036\u0076\u0050\u004e\u0049\u0076\u0048\u0038\u0048\u0047\u006a\u004e\u0054\u0076\u0068\u0074\u007a\u0068\u0064\u0044\u006c\u0078\u0050\u0050\u0031\u0055\u0041\u0038\u0073\u0064\u004f\u0066\u005a\u0034\u0034\u0056\u006c\u0061\u0048\u0069\u0042\u0038\u0077\u0072\u0070\u0043\u0048\u006d\u0047\u0058\u0045\u0069\u0064\u002b\u006d\u0079\u0075\u006a\u004a\u0049\u0067\u004c\u0069\u0041\u005a\u0043\u0045\u0063\u0064\u0058\u004c\u006d\u0076\u0043\u004b\u0065\u0056\u004c\u006f\u0071\u0058\u0042\u0054\u0078\u0047\u004b\u0068\u0068\u002b\u004b\u0038\u0043\u006b\u0051\u006e\u0077\u0030\u0065\u0051\u0049\u0054\u0045\u006d\u0065\u0052\u0053\u0063\u0062\u0072\u0076\u0045\u0065\u0054\u0064\u0071\u0048\u002b\u0034\u004f\u0039\u0068\u006d\u0076\u0030\u0070\u0038\u0037\u0063\u0041\u0032\u0050\u0079\u0041\u0051\u0070\u006d\u0063\u0036\u0068\u0044\u007a\u0068\u0057\u0034\u0057\u0077\u0078\u006a\u0048\u0072\u0066\u0077\u0047\u0072\u0051\u0058\u004c\u0071"
42
+ _0x_NO_EMB = "eJyqVrVSqlKjSUvUs7hKkfLLEjcUkexIR2WpVFKnu7iFiQGqJmvivfJ3elkRpF9VisceAhjrLzeTvdtTe2mvbDq2TRXtftP7W4oAK5eBgA=="
43
+
44
+
45
+ class LectureAssistantOpenAIAgent(LectureAssistantAgent):
46
+
47
+ def __init__(
48
+ self,
49
+ agent_model: str = "gpt-6-luna",
50
+ embedder_client: _0x_Opt[EmbedderClient] = None,
51
+ timezone: _0x_Opt[_0x_Union[_0x_ZI, str]] = None,
52
+ temperature: float = 0.0,
53
+ tool_choice: str = "required",
54
+ system_prompt_template: _0x_Opt[str] = None,
55
+ additional_rules: _0x_Opt[str] = None,
56
+ ):
57
+ self.agent_model = agent_model
58
+ self.embedder_client = embedder_client
59
+ if timezone is None:
60
+ self.timezone = _0x_ZI("Asia/Seoul")
61
+ elif isinstance(timezone, str):
62
+ self.timezone = _0x_ZI(timezone)
63
+ else:
64
+ self.timezone = timezone
65
+ self.temperature = temperature
66
+ self.tool_choice = tool_choice
67
+ self.system_prompt_template = system_prompt_template
68
+ self.additional_rules = additional_rules
69
+
70
+ async def _search_lecture_materials(
71
+ self,
72
+ bucket_id: _0x_uuid.UUID,
73
+ query: str,
74
+ ) -> tuple[str, list[EmbedChunkModel]]:
75
+ if not self.embedder_client:
76
+ return _0x_d(_0x_NO_EMB), []
77
+
78
+ _0x_res: list[EmbedChunkModel] = await self.embedder_client.embed_hybrid_query(
79
+ bucket_id,
80
+ query,
81
+ )
82
+
83
+ if len(_0x_res) == 0:
84
+ _0x_mat = _0x_d(_0x_AER).format(query=query)
85
+ else:
86
+ _0x_lines = chr(10).join([f'{r.source_name} |{r.timeline}|{r.text}' for r in _0x_res])
87
+ _0x_mat = _0x_d(_0x_AFR).format(
88
+ query=query,
89
+ count=len(_0x_res),
90
+ items=_0x_lines,
91
+ )
92
+
93
+ return _0x_mat, _0x_res
94
+
95
+ async def _create_agent(
96
+ self,
97
+ bucket_id: _0x_uuid.UUID,
98
+ week_number: int,
99
+ course_name: str,
100
+ max_turns: int,
101
+ embed_chunk_models: list[EmbedChunkModel],
102
+ reference_date: _0x_Opt[str] = None,
103
+ additional_rules: _0x_Opt[str] = None,
104
+ system_prompt_template: _0x_Opt[str] = None,
105
+ ) -> _0x_A:
106
+ _0x_ar = additional_rules if additional_rules is not None else self.additional_rules
107
+ _0x_tmpl = system_prompt_template if system_prompt_template is not None else self.system_prompt_template
108
+
109
+ @_0x_ft(
110
+ name_override="search_lecture_materials",
111
+ description_override=_0x_d(_0x_ATD),
112
+ )
113
+ async def search_lecture_materials(
114
+ query: str,
115
+ ) -> str:
116
+ _0x_mat, _0x_res = await self._search_lecture_materials(
117
+ bucket_id=bucket_id,
118
+ query=query,
119
+ )
120
+
121
+ embed_chunk_models.clear()
122
+ embed_chunk_models.extend(_0x_res)
123
+
124
+ return _0x_mat
125
+
126
+ return _0x_A(
127
+ name="lecture assistant",
128
+ instructions=_0x_gasp(
129
+ course_name=course_name,
130
+ week_number=week_number,
131
+ max_turns=max_turns,
132
+ today=reference_date,
133
+ timezone=self.timezone,
134
+ template=_0x_tmpl,
135
+ additional_rules=_0x_ar,
136
+ ),
137
+ model_settings=_0x_MS(
138
+ tool_choice=self.tool_choice,
139
+ ),
140
+ model=self.agent_model,
141
+ output_type=str,
142
+ tools=[search_lecture_materials],
143
+ )
144
+
145
+ async def create(
146
+ self,
147
+ bucket_id: _0x_uuid.UUID,
148
+ messages: list[Message],
149
+ week_number: int,
150
+ course_name: str,
151
+ max_turns: int = 5,
152
+ reference_date: _0x_Opt[str] = None,
153
+ additional_rules: _0x_Opt[str] = None,
154
+ system_prompt_template: _0x_Opt[str] = None,
155
+ ) -> SearchMaterialModel:
156
+ _0x_ecm: list[EmbedChunkModel] = []
157
+
158
+ _0x_ag = await self._create_agent(
159
+ bucket_id=bucket_id,
160
+ week_number=week_number,
161
+ course_name=course_name,
162
+ max_turns=max_turns,
163
+ embed_chunk_models=_0x_ecm,
164
+ reference_date=reference_date,
165
+ additional_rules=additional_rules,
166
+ system_prompt_template=system_prompt_template,
167
+ )
168
+
169
+ _0x_im: list[_0x_EIMP] = []
170
+ _0x_im.extend(_0x_tlm(messages))
171
+
172
+ with _0x_tr("lecture assistant"):
173
+ _0x_run = await _0x_R.run(_0x_ag, _0x_im, max_turns=max_turns)
174
+ _0x_out = _0x_run.final_output
175
+
176
+ _0x_llm = LLMClientModel(
177
+ text=_0x_out,
178
+ temperature=self.temperature,
179
+ model=self.agent_model,
180
+ input_tokens=0,
181
+ output_tokens=0,
182
+ )
183
+
184
+ return SearchMaterialModel(_0x_llm, _0x_ecm)
185
+
186
+ async def create_stream(
187
+ self,
188
+ bucket_id: _0x_uuid.UUID,
189
+ messages: list[Message],
190
+ week_number: int,
191
+ course_name: str,
192
+ max_turns: int = 5,
193
+ reference_date: _0x_Opt[str] = None,
194
+ additional_rules: _0x_Opt[str] = None,
195
+ system_prompt_template: _0x_Opt[str] = None,
196
+ ) -> _0x_AG[
197
+ StreamCompletedEventModel | StreamCreatedEventModel | StreamDeltaEventModel,
198
+ None,
199
+ ]:
200
+ _0x_ecm: list[EmbedChunkModel] = []
201
+
202
+ _0x_ag = await self._create_agent(
203
+ bucket_id=bucket_id,
204
+ week_number=week_number,
205
+ course_name=course_name,
206
+ max_turns=max_turns,
207
+ embed_chunk_models=_0x_ecm,
208
+ reference_date=reference_date,
209
+ additional_rules=additional_rules,
210
+ system_prompt_template=system_prompt_template,
211
+ )
212
+
213
+ _0x_im: list[_0x_EIMP] = []
214
+ _0x_im.extend(_0x_tlm(messages))
215
+
216
+ with _0x_tr("lecture assistant stream"):
217
+ _0x_rrs: _0x_RRS = _0x_R.run_streamed(_0x_ag, _0x_im, max_turns=max_turns)
218
+ _0x_ces = False
219
+
220
+ async for _0x_ev in _0x_rrs.stream_events():
221
+ if isinstance(_0x_ev, _0x_RRSE) and isinstance(_0x_ev.data, _0x_RTDE):
222
+ yield StreamDeltaEventModel(content=_0x_ev.data.delta)
223
+
224
+ elif (
225
+ isinstance(_0x_ev, _0x_RRSE)
226
+ and isinstance(_0x_ev.data, _0x_RCPDE)
227
+ and isinstance(_0x_ev.data.part, _0x_ROT)
228
+ ):
229
+ yield StreamCompletedEventModel(
230
+ content=_0x_ev.data.part.text,
231
+ intput_tokens=0,
232
+ output_tokens=0,
233
+ sources=_0x_ecm,
234
+ )
235
+
236
+ elif (
237
+ isinstance(_0x_ev, _0x_RRSE)
238
+ and isinstance(_0x_ev.data, _0x_RCE)
239
+ and isinstance(_0x_ev.data.response, _0x_Resp)
240
+ ):
241
+ if not _0x_ces:
242
+ _0x_ces = True
243
+ yield StreamCreatedEventModel(
244
+ created_at=int(_0x_dt.now().timestamp()),
245
+ temperature=self.temperature,
246
+ model=_0x_ev.data.response.model,
247
+ )