ckit_ask_model
The ckit_ask_model module provides functions for activating bots, creating subchats, and manipulating thread messages.
Bot Activation
bot_activate()
Start a new conversation with a bot:
from flexus_client_kit import ckit_ask_model
result = await ckit_ask_model.bot_activate( client=fclient, who_is_asking="my_service", persona_id=rcx.persona.persona_id, first_question="Analyze this data: ...", title="Data Analysis", fexp_name="analyst", # Optional: specific expert)
print(f"Thread created: {result.ft_id}")Parameters
| Parameter | Type | Description |
|---|---|---|
client | FlexusClient | API client |
who_is_asking | str | Identifier for logging |
persona_id | str | Target bot’s persona ID |
first_question | str | Initial message |
title | str | Thread title |
fexp_name | str | Expert name (default: “default”) |
first_call | str | Optional initial tool call JSON |
context_files | list | Files to include as context |
Returns
FThreadOutput with:
ft_id— Thread IDft_title— Thread titleft_need_assistant— Waiting for LLM response
Subchats
Subchats are isolated conversations that run in parallel and return results to the parent tool call.
bot_subchat_create_multiple()
Create one or more subchats:
from flexus_client_kit import ckit_ask_model, ckit_cloudtool
@rcx.on_tool_call("analyze_multiple")async def handle(toolcall, args): items = args["items"] # ["item1", "item2", "item3"]
subchats = await ckit_ask_model.bot_subchat_create_multiple( client=fclient, who_is_asking="multi_analyzer", persona_id=rcx.persona.persona_id, first_question=[f"Analyze: {item}" for item in items], first_calls=["null" for _ in items], # No initial tool calls title=[f"Analysis: {item}" for item in items], fcall_id=toolcall.fcall_id, fexp_name="analyst", )
# This pauses until all subchats complete raise ckit_cloudtool.WaitForSubchats(subchats)Parameters
| Parameter | Type | Description |
|---|---|---|
client | FlexusClient | API client |
who_is_asking | str | Identifier for logging |
persona_id | str | Bot’s persona ID |
first_question | List[str] | Initial messages (one per subchat) |
first_calls | List[str] | Initial tool calls JSON (“null” for none) |
title | List[str] | Titles for each subchat |
fcall_id | str | Parent tool call ID |
fexp_name | str | Expert to use |
Returns
List[FThreadOutput] — Created subchat threads.
Subchat Completion
Subchats must complete within 10 minutes. The subchat expert’s Lark kernel must set subchat_result to signal completion. Without this, subchats will timeout.
Subchat Lark Kernel
The expert used for subchats needs a kernel that sets subchat_result:
# In install script, expert definition:FMarketplaceExpertInput( fexp_system_prompt=ANALYST_PROMPT, fexp_python_kernel="""# Check if analysis is completemsg = messages[-1]if msg["role"] == "assistant" and "ANALYSIS_COMPLETE" in str(msg.get("content", "")): subchat_result = msg["content"]elif msg["role"] == "assistant" and not msg.get("tool_calls"): # No tool calls and no marker = ask to complete post_cd_instruction = "Finish your analysis and include ANALYSIS_COMPLETE at the end."""", fexp_app_capture_tools=tools_json,)Message Operations
thread_messages_create_multiple()
Add messages to a thread:
await ckit_ask_model.thread_messages_create_multiple( client=fclient, ft_id=thread_id, messages=[ {"role": "user", "content": "Additional context"}, {"role": "context_file", "content": "File contents here..."}, ],)Message Roles
| Role | Purpose |
|---|---|
user | User input |
assistant | Bot response |
tool | Tool call result |
cd_instruction | Injected instruction (from kernel) |
context_file | File/document context |
Data Structures
FThreadOutput
@dataclassclass FThreadOutput: ft_id: str # Thread ID ft_title: str # Thread title ft_need_assistant: int # >0 if waiting for LLM ft_need_tool_calls: int # >0 if waiting for tools ft_need_user: int # >0 if waiting for user ft_error: str # Error message if any ft_coins: int # Coins spent ft_budget: int # Budget limit ft_fexp_id: str # Expert ID ft_toolset: str # JSON of allowed toolsFThreadMessageOutput
@dataclassclass FThreadMessageOutput: ftm_id: str # Message ID ftm_ft_id: str # Thread ID ftm_role: str # Message role ftm_content: str # Message content ftm_tool_calls: List # Tool calls (for assistant) ftm_call_id: str # Tool call ID (for tool results) ftm_provenance: str # JSON metadata ftm_created_ts: datetimePatterns
Parallel Analysis with Subchats
@rcx.on_tool_call("deep_research")async def handle(toolcall, args): topic = args["topic"]
# Create 3 parallel research threads subchats = await ckit_ask_model.bot_subchat_create_multiple( client=fclient, who_is_asking="deep_researcher", persona_id=rcx.persona.persona_id, first_question=[ f"Research academic sources on: {topic}", f"Research industry reports on: {topic}", f"Research news and trends on: {topic}", ], first_calls=["null", "null", "null"], title=["Academic", "Industry", "News"], fcall_id=toolcall.fcall_id, fexp_name="researcher", )
raise ckit_cloudtool.WaitForSubchats(subchats)Scheduled Bot Activation
# External service activates a bot on scheduleasync def daily_report_trigger(): await ckit_ask_model.bot_activate( client=fclient, who_is_asking="daily_scheduler", persona_id=report_bot_persona_id, first_question="Generate daily sales report for yesterday", title=f"Daily Report {date.today()}", )Sequential Chat with Context
# First message starts the threadresult = await ckit_ask_model.bot_activate( client=fclient, who_is_asking="workflow", persona_id=rcx.persona.persona_id, first_question="Start processing", title="Workflow",)
# Wait for response...
# Add more contextawait ckit_ask_model.thread_messages_create_multiple( client=fclient, ft_id=result.ft_id, messages=[ {"role": "context_file", "content": document_content}, {"role": "user", "content": "Now analyze the document above"}, ],)Complete Example
from flexus_client_kit import ckit_ask_model, ckit_cloudtool
COMPARE_TOOL = ckit_cloudtool.CloudTool( strict=True, name="compare_options", description="Compare multiple options in parallel", parameters={ "type": "object", "properties": { "options": { "type": "array", "items": {"type": "string"}, "description": "Options to compare", }, "criteria": { "type": "string", "description": "Comparison criteria", }, }, "required": ["options", "criteria"], "additionalProperties": False, },)
async def main_loop(fclient, rcx): @rcx.on_tool_call(COMPARE_TOOL.name) async def handle_compare(toolcall, args): options = args["options"] criteria = args["criteria"]
if len(options) < 2: return "Need at least 2 options to compare"
if len(options) > 5: return "Maximum 5 options allowed"
# Create parallel evaluation subchats subchats = await ckit_ask_model.bot_subchat_create_multiple( client=fclient, who_is_asking="option_comparator", persona_id=rcx.persona.persona_id, first_question=[ f"Evaluate '{opt}' against criteria: {criteria}. " f"Score 1-10 and explain. End with EVALUATION_COMPLETE." for opt in options ], first_calls=["null" for _ in options], title=[f"Evaluate: {opt}" for opt in options], fcall_id=toolcall.fcall_id, fexp_name="evaluator", # Must have kernel that sets subchat_result )
raise ckit_cloudtool.WaitForSubchats(subchats)
# Main loop while not ckit_shutdown.shutdown_event.is_set(): await rcx.unpark_collected_events(sleep_if_no_work=10.0)