main
py 115 lines 3.76 KB
Raw
1 """Shared chat-context helpers for connector handlers."""
2
3 from __future__ import annotations
4
5 from contextlib import nullcontext
6 from typing import Any
7
8
9 class ConnectorContextError(Exception):
10 def __init__(
11 self,
12 message: str,
13 *,
14 status_code: int = 400,
15 code: str = "BAD_REQUEST",
16 ) -> None:
17 super().__init__(message)
18 self.status_code = status_code
19 self.code = code
20
21
22 def get_existing_context(
23 context_id: str,
24 *,
25 agent_profile: str | None = None,
26 project_name: str | None = None,
27 ):
28 from agent import AgentContext
29 from helpers import projects
30
31 context = AgentContext.get(context_id)
32 if context is None:
33 raise ConnectorContextError(
34 "Context not found",
35 status_code=404,
36 code="CONTEXT_NOT_FOUND",
37 )
38
39 if agent_profile and getattr(context.agent0.config, "profile", None) != agent_profile:
40 raise ConnectorContextError(
41 "Cannot change agent_profile on existing context",
42 status_code=400,
43 code="INVALID_AGENT_PROFILE",
44 )
45
46 existing_project = context.get_data(projects.CONTEXT_DATA_KEY_PROJECT)
47 if project_name and existing_project and existing_project != project_name:
48 raise ConnectorContextError(
49 "Project can only be set on first message",
50 status_code=400,
51 code="PROJECT_CONFLICT",
52 )
53
54 return context
55
56
57 def create_context(
58 *,
59 lock: Any | None = None,
60 current_context_id: str | None = None,
61 agent_profile: str | None = None,
62 project_name: str | None = None,
63 ):
64 from agent import AgentContext, AgentContextType
65 from helpers import projects, settings
66 from helpers.state_monitor_integration import mark_dirty_all
67 from initialize import initialize_agent
68 from plugins._model_config.helpers.model_config import is_chat_override_allowed
69
70 override_settings: dict[str, str] = {}
71 if agent_profile:
72 override_settings["agent_profile"] = agent_profile
73
74 with lock if lock is not None else nullcontext():
75 current_context = AgentContext.get(current_context_id or "") if current_context_id else None
76
77 context = AgentContext(
78 config=initialize_agent(override_settings=override_settings),
79 type=AgentContextType.USER,
80 set_current=True,
81 )
82
83 if current_context and settings.get_settings().get("chat_inherit_project", True):
84 current_project = current_context.get_data(projects.CONTEXT_DATA_KEY_PROJECT)
85 if current_project:
86 context.set_data(projects.CONTEXT_DATA_KEY_PROJECT, current_project)
87
88 current_project_output = current_context.get_output_data(
89 projects.CONTEXT_DATA_KEY_PROJECT
90 )
91 if current_project_output:
92 context.set_output_data(
93 projects.CONTEXT_DATA_KEY_PROJECT,
94 current_project_output,
95 )
96
97 if current_context:
98 model_override = current_context.get_data("chat_model_override")
99 if model_override and is_chat_override_allowed(context.agent0):
100 context.set_data("chat_model_override", model_override)
101
102 if project_name:
103 try:
104 try:
105 projects.activate_project(context.id, project_name, mark_dirty=False)
106 except TypeError as exc:
107 if "mark_dirty" not in str(exc):
108 raise
109 projects.activate_project(context.id, project_name)
110 except Exception:
111 AgentContext.remove(context.id)
112 raise
113
114 mark_dirty_all(reason="plugins._a0_connector.chat_context.create_context")
115 return context