Skip to content

Commit c20f602

Browse files
committed
feat: add examples for re-run section
1 parent 032cc63 commit c20f602

7 files changed

Lines changed: 170 additions & 53 deletions

File tree

examples/automating_section.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import os
2+
from thesis_py import Thesis
3+
from thesis_py.api_schema import CreateNewConversationIntegrationRequest, ResearchMode
4+
from thesis_py.research.events import from_raw_events_to_pairs
5+
from time import sleep
6+
7+
from thesis_py.research.events.action.agent import AgentFinishAction
8+
from thesis_py.research.events.schema.action import ActionType
9+
from thesis_py.research.events.schema.agent import AgentState
10+
from thesis_py.research.events.observation.agent import AgentStateChangedObservation
11+
12+
THESIS_API_KEY = os.environ.get("THESIS_API_KEY")
13+
14+
if not THESIS_API_KEY:
15+
raise ValueError("THESIS_API_KEY environment variable not set!")
16+
17+
thesis = Thesis(THESIS_API_KEY)
18+
19+
20+
def main():
21+
response = thesis.create_conversation(
22+
CreateNewConversationIntegrationRequest(
23+
initial_user_msg="What's the new DeFi meta recently that I can ape in? Give me detailed info about Project name, project description, CEOs, backers, current X mindshare percentage, main project token, current token price, price change within 30 days. Give me 5 projects that have at least 100% price change within 30 days.",
24+
research_mode=ResearchMode.DEEP_RESEARCH,
25+
space_id=int(os.environ.get("THESIS_SPACE_ID")),
26+
space_section_id=int(os.environ.get("THESIS_SPACE_SECTION_ID")),
27+
mcp_disable={
28+
"hyperwhales": True,
29+
"liquidity": True,
30+
"stable": True,
31+
"browser_mcp": True,
32+
"investing_news": True,
33+
"jina": True,
34+
"arbitraging": True,
35+
"netlify": True,
36+
"meme": True,
37+
"perpetual_whales_analysis": True,
38+
"defi_earn": True,
39+
"token_metrics": True,
40+
},
41+
)
42+
)
43+
44+
print(response.conversation_id)
45+
46+
print("Waiting for Thesis.io to finish the conversation...")
47+
last_printed_index = -1
48+
49+
while True:
50+
finished = False
51+
response = thesis.get_conversation_by_id(response.conversation_id)
52+
events = from_raw_events_to_pairs(response.events)
53+
54+
# Print new events from last_printed_index + 1 onward
55+
new_events = events[last_printed_index + 1 :]
56+
if new_events:
57+
print("-" * 200)
58+
for event in new_events:
59+
print(event)
60+
last_printed_index = len(events) - 1
61+
62+
# Check for finished state
63+
for event in reversed(events):
64+
if isinstance(event[1], AgentStateChangedObservation) and (
65+
event[1].agent_state == AgentState.FINISHED
66+
or event[1].agent_state == AgentState.AWAITING_USER_INPUT
67+
):
68+
finished = True
69+
break
70+
if isinstance(event[0], AgentFinishAction) and event[0].task_completed:
71+
finished = True
72+
break
73+
if event[0].action == ActionType.FINISH and event[0].task_completed:
74+
finished = True
75+
break
76+
if finished:
77+
break
78+
sleep(5)
79+
80+
81+
if __name__ == "__main__":
82+
main()

examples/get_conversation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
thesis = Thesis(THESIS_API_KEY)
1212

13-
response = thesis.get_conversation_by_id("b3052a322b5b4149a4c46a02584e2dbb")
13+
response = thesis.get_conversation_by_id(os.environ.get("THESIS_CONVERSATION_ID"))
1414

1515
pairs = from_raw_events_to_pairs(response.events[:2])
1616

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from py_clob_client.client import ClobClient
2+
3+
client = ClobClient("https://clob.polymarket.com") # Level 0 (no auth)
4+
5+
ok = client.get_ok()
6+
time = client.get_server_time()
7+
print(ok, time)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "thesis-py"
77
version = "1.0.2"
88
description = "Python SDK for Thesis.io APIs."
99
readme = "README.md"
10-
requires-python = ">=3.9"
10+
requires-python = ">=3.9.10"
1111
license = { text = "GNU General Public License v3.0" }
1212
authors = [{ name = "Oraichain Labs", email = "duc@orai.io" }]
1313
dependencies = [

thesis_py/api_schema/conversations.py

Lines changed: 76 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,152 +2,180 @@
22

33
from thesis_py.research.events.schema.research import ResearchMode
44

5+
56
# Response Models
67
class ConversationCreateResponse(BaseModel):
78
status: str = Field(
8-
description="Response status, always 'ok' for successful creation", example='ok'
9+
description="Response status, always 'ok' for successful creation", example="ok"
910
)
1011
conversation_id: str = Field(
11-
description='Unique identifier for the created conversation',
12-
example='conv_abc123def456',
12+
description="Unique identifier for the created conversation",
13+
example="conv_abc123def456",
1314
)
1415

16+
1517
class ConversationEvent(BaseModel):
16-
action: str = Field(description='Type of action/event', example='message')
17-
source: str = Field(description='Source of the event (user/agent)', example='user')
18+
action: str = Field(description="Type of action/event", example="message")
19+
source: str = Field(description="Source of the event (user/agent)", example="user")
1820
message: str = Field(
19-
description='Content of the message or action',
20-
example='Please review this code',
21+
description="Content of the message or action",
22+
example="Please review this code",
2123
)
2224
timestamp: str = Field(
23-
description='ISO timestamp when the event occurred',
24-
example='2024-01-15T10:30:00Z',
25+
description="ISO timestamp when the event occurred",
26+
example="2024-01-15T10:30:00Z",
2527
)
2628

2729

2830
class ConversationDetailResponse(BaseModel):
2931
conversation_id: str = Field(
30-
description='Unique conversation identifier', example='conv_abc123def456'
32+
description="Unique conversation identifier", example="conv_abc123def456"
3133
)
32-
title: str = Field(description='Conversation title', example='Code Review Session')
33-
status: str = Field(description='Current conversation status', example='RUNNING')
34+
title: str = Field(description="Conversation title", example="Code Review Session")
35+
status: str = Field(description="Current conversation status", example="RUNNING")
3436
created_at: str = Field(
35-
description='ISO timestamp when conversation was created',
36-
example='2024-01-15T10:30:00Z',
37+
description="ISO timestamp when conversation was created",
38+
example="2024-01-15T10:30:00Z",
3739
)
3840
last_updated_at: str = Field(
39-
description='ISO timestamp of last activity', example='2024-01-15T11:45:00Z'
41+
description="ISO timestamp of last activity", example="2024-01-15T11:45:00Z"
4042
)
4143
selected_repository: str | None = Field(
42-
description='Associated repository if any', example='user/project-repo'
44+
description="Associated repository if any", example="user/project-repo"
4345
)
4446
research_mode: str | None = Field(
45-
description='Research mode used in conversation', example='deep_research'
47+
description="Research mode used in conversation", example="deep_research"
4648
)
4749
events: list[dict] | None = Field(
48-
description='List of conversation events/messages', default=None
50+
description="List of conversation events/messages", default=None
4951
)
5052
final_result: str | dict | None = Field(
51-
description='Final result if conversation is completed', default=None
53+
description="Final result if conversation is completed", default=None
5254
)
53-
55+
56+
5457
class CreateNewConversationIntegrationRequest(BaseModel):
5558
initial_user_msg: str | None = Field(
5659
None,
57-
description='Initial message to start the conversation',
60+
description="Initial message to start the conversation",
5861
example="What's the new DeFi meta recently that I can ape in?",
5962
)
6063
research_mode: ResearchMode | None = Field(
61-
None, description='Research mode for the conversation', example='deep_research'
64+
None, description="Research mode for the conversation", example="deep_research"
6265
)
6366
space_id: int | None = Field(
6467
None,
65-
description='Your space ID. You can find it via your created space',
68+
description="Your space ID. You can find it via your created space",
6669
example=123,
6770
)
6871
space_section_id: int | None = Field(
6972
None,
70-
description='Your space section ID. You can find it via your created space',
73+
description="Your space section ID. You can find it via your created space",
7174
example=456,
7275
)
7376
thread_follow_up: int | None = Field(
74-
None, description='Thread ID for follow-up conversations', example=789
77+
None, description="Thread ID for follow-up conversations", example=789
7578
)
7679
followup_discover_id: str | None = Field(
7780
None,
78-
description='Discovery ID for follow-up research',
79-
example='discover_abc123',
81+
description="Discovery ID for follow-up research",
82+
example="discover_abc123",
8083
)
8184
mcp_disable: dict[str, bool] | None = Field(
8285
None,
83-
description='MCP tools to disable for this conversation',
86+
description="MCP tools to disable for this conversation. The example has a fool list of MCP tools to disable.",
87+
example={
88+
"hyperwhales": True,
89+
"liquidity": True,
90+
"stable": True,
91+
"browser_mcp": True,
92+
"x_ai_search_tool": True,
93+
"investing_news": True,
94+
"jina": True,
95+
"arbitraging": True,
96+
"netlify": True,
97+
"meme": True,
98+
"perpetual_whales_analysis": True,
99+
"price": True,
100+
"defi_earn": True,
101+
"ratsa_signal": True,
102+
"astar_stable_yield": True,
103+
"crypto_insight_search_service": True,
104+
"token_metrics": True,
105+
},
84106
)
85107
system_prompt: str | None = Field(
86108
None,
87-
description='Custom system prompt to guide the AI behavior',
109+
description="Custom system prompt to guide the AI behavior",
88110
example="You are a DeFi gigachad who's always ahead of the new DeFi meta.",
89111
)
90-
112+
91113
@field_serializer("research_mode")
92-
def serialize_research_mode(self, research_mode: ResearchMode | None, _info) -> str | None:
114+
def serialize_research_mode(
115+
self, research_mode: ResearchMode | None, _info
116+
) -> str | None:
93117
return research_mode.value if research_mode else None
94118

119+
95120
class CreateChatConversationIntegrationRequest(BaseModel):
96121
initial_user_msg: str | None = Field(
97122
None,
98-
description='Initial message for the chat conversation',
123+
description="Initial message for the chat conversation",
99124
example="Let's have a casual conversation about DeFi",
100125
)
101126
system_prompt: str | None = Field(
102127
None,
103128
description="System prompt to set the AI's behavior in chat mode",
104-
example='You are a friendly AI assistant who explains complex topics simply',
129+
example="You are a friendly AI assistant who explains complex topics simply",
105130
)
106131

107132

108133
class CreateDeepResearchConversationIntegrationRequest(BaseModel):
109134
initial_user_msg: str | None = Field(
110135
None,
111-
description='Initial research query to begin deep analysis',
112-
example='Research the latest developments in DeFi',
136+
description="Initial research query to begin deep analysis",
137+
example="Research the latest developments in DeFi",
113138
)
114139
mcp_disable: dict[str, bool] | None = Field(
115140
None,
116-
description='MCP tools to disable during deep research',
141+
description="MCP tools to disable during deep research",
117142
)
118143
system_prompt: str | None = Field(
119144
None,
120-
description='System prompt for deep research mode behavior',
121-
example='You are a thorough DeFi researcher who provides comprehensive analysis with citations',
145+
description="System prompt for deep research mode behavior",
146+
example="You are a thorough DeFi researcher who provides comprehensive analysis with citations",
122147
)
123148

149+
124150
class JoinConversationIntegrationRequest(BaseModel):
125151
conversation_id: str | None = Field(
126152
None,
127-
description='ID of the existing conversation to join',
128-
example='conv_abc123def456',
153+
description="ID of the existing conversation to join",
154+
example="conv_abc123def456",
129155
)
130156
user_prompt: str | None = Field(
131157
None,
132-
description='Message to send when joining the conversation',
133-
example='Please review the code we discussed earlier',
158+
description="Message to send when joining the conversation",
159+
example="Please review the code we discussed earlier",
134160
)
135161
research_mode: ResearchMode | None = Field(
136162
None,
137-
description='Research mode to use in the conversation. Must be one of: chat, deep_research, follow_up',
163+
description="Research mode to use in the conversation. Must be one of: chat, deep_research, follow_up",
138164
example=ResearchMode.DEEP_RESEARCH.value,
139165
)
140166
latest_event_id: int | None = Field(
141167
None,
142-
description='ID of the latest event to resume from',
168+
description="ID of the latest event to resume from",
143169
example=123,
144170
)
145171
x_device_id: str | None = Field(
146172
None,
147-
description='Device ID to use for the conversation',
148-
example='123',
173+
description="Device ID to use for the conversation",
174+
example="123",
149175
)
150176

151177
@field_serializer("research_mode")
152-
def serialize_research_mode(self, research_mode: ResearchMode | None, _info) -> str | None:
153-
return research_mode.value if research_mode else None
178+
def serialize_research_mode(
179+
self, research_mode: ResearchMode | None, _info
180+
) -> str | None:
181+
return research_mode.value if research_mode else None

thesis_py/api_schema/spaces.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ class SpaceDetailResponse(BaseModel):
332332
class SpaceSection(BaseModel):
333333
id: str = Field(description="Unique section identifier", example="555")
334334
spaceId: str = Field(description="Space identifier", example="724")
335+
conversationId: Optional[str] = Field(description="Conversation ID", example="abc123", default=None)
335336
name: Optional[str] = Field(
336337
description="Section name", default=None, example="Overview"
337338
)
@@ -341,7 +342,6 @@ class SpaceSection(BaseModel):
341342
prompt: Optional[str] = Field(
342343
description="Section prompt", default=None, example="Create a chart..."
343344
)
344-
conversationId: str = Field(description="Conversation ID", example="abc123")
345345
outputType: Optional[str] = Field(
346346
description="Output type", default=None, example="bar_chart"
347347
)

uv.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)