contentgrid-assistant-api 0.0.3__tar.gz → 0.0.4__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 (29) hide show
  1. {contentgrid_assistant_api-0.0.3/src/contentgrid_assistant_api.egg-info → contentgrid_assistant_api-0.0.4}/PKG-INFO +2 -1
  2. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/pyproject.toml +1 -0
  3. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/app.py +14 -3
  4. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/config.py +23 -0
  5. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/routers/agent_home.py +17 -3
  6. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/routers/message_router.py +28 -5
  7. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/routers/thread_router.py +29 -4
  8. contentgrid_assistant_api-0.0.4/src/contentgrid_assistant_api/tracing.py +67 -0
  9. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4/src/contentgrid_assistant_api.egg-info}/PKG-INFO +2 -1
  10. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api.egg-info/SOURCES.txt +3 -0
  11. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api.egg-info/requires.txt +1 -0
  12. contentgrid_assistant_api-0.0.4/src/contentgrid_assistant_api.egg-info/scm_file_list.json +24 -0
  13. contentgrid_assistant_api-0.0.4/src/contentgrid_assistant_api.egg-info/scm_version.json +8 -0
  14. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/LICENSE +0 -0
  15. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/README.md +0 -0
  16. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/pytest.ini +0 -0
  17. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/setup.cfg +0 -0
  18. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/setup.py +0 -0
  19. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/db/repositories/thread_repository.py +0 -0
  20. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/db/types/message.py +0 -0
  21. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/db/types/thread.py +0 -0
  22. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/dependencies.py +0 -0
  23. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/types/agents.py +0 -0
  24. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api/types/context.py +0 -0
  25. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api.egg-info/dependency_links.txt +0 -0
  26. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/src/contentgrid_assistant_api.egg-info/top_level.txt +0 -0
  27. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/tests/mock_agent.py +0 -0
  28. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/tests/test_thread_access_control.py +0 -0
  29. {contentgrid_assistant_api-0.0.3 → contentgrid_assistant_api-0.0.4}/tests/test_tools_endpoint.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: contentgrid-assistant-api
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: FastAPI wrapper for contentgrid assistants
5
5
  Author-email: Ranec Belpaire <ranec.belpaire@xenit.eu>
6
6
  License: Copyright 2024 Xenit Solutions
@@ -30,6 +30,7 @@ Requires-Dist: langchain>=1.2.3
30
30
  Requires-Dist: langchain_openai>=1.1.7
31
31
  Requires-Dist: langgraph>=1.0.5
32
32
  Requires-Dist: langgraph-checkpoint-postgres>=3.0.2
33
+ Requires-Dist: langfuse>=3.0.0
33
34
  Requires-Dist: python-dotenv>=1.1.1
34
35
  Requires-Dist: requests<3,>=2.32.5
35
36
  Requires-Dist: types-requests>=2.32.4
@@ -25,6 +25,7 @@ dependencies = [
25
25
  "langchain_openai >= 1.1.7",
26
26
  "langgraph >= 1.0.5",
27
27
  "langgraph-checkpoint-postgres >= 3.0.2",
28
+ "langfuse >= 3.0.0",
28
29
  "python-dotenv >= 1.1.1",
29
30
  "requests >= 2.32.5, < 3",
30
31
  "types-requests >= 2.32.4",
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ from contextlib import asynccontextmanager
2
3
  from typing import List, Optional
3
4
  from fastapi import Depends, FastAPI, status, Request
4
5
  from fastapi.middleware.cors import CORSMiddleware
@@ -9,8 +10,9 @@ from contentgrid_extension_helpers.logging import setup_json_logging
9
10
  from contentgrid_extension_helpers.problem_response import ProblemResponse
10
11
 
11
12
  from contentgrid_assistant_api.routers.agent_home import generate_agent_home_router
12
- from contentgrid_assistant_api.config import AssistantExtensionConfig, DatabaseConfig
13
+ from contentgrid_assistant_api.config import AssistantExtensionConfig, DatabaseConfig, LangfuseConfig
13
14
  from contentgrid_assistant_api.types.agents import Agent, AgentHomeResponse
15
+ from contentgrid_assistant_api.tracing import setup_langfuse, shutdown_langfuse
14
16
  from pydantic import HttpUrl
15
17
 
16
18
 
@@ -19,14 +21,16 @@ class ContentGridAssistantAPI(FastAPI):
19
21
 
20
22
  def __init__(self,
21
23
  extension_config: AssistantExtensionConfig | None = None,
22
- database_config: DatabaseConfig | None = None,
24
+ database_config: DatabaseConfig | None = None,
25
+ langfuse_config: LangfuseConfig | None = None,
23
26
  agents: List[Agent] = [],
24
27
  *args, **kwargs):
25
- super().__init__(*args, **kwargs)
26
28
  self.extension_config = extension_config or AssistantExtensionConfig()
27
29
  self.database_config = database_config or DatabaseConfig()
30
+ self.langfuse_config = langfuse_config or LangfuseConfig()
28
31
 
29
32
  self._setup_logging()
33
+ super().__init__(*args, lifespan=self._lifespan, **kwargs)
30
34
  if not self.extension_config.production:
31
35
  self._setup_cors()
32
36
  self._setup_hal_response()
@@ -55,6 +59,13 @@ class ContentGridAssistantAPI(FastAPI):
55
59
  if self.extension_config.production:
56
60
  setup_json_logging()
57
61
 
62
+ @asynccontextmanager
63
+ async def _lifespan(self, app: "ContentGridAssistantAPI"):
64
+ """Manage application lifespan: initialize and shut down Langfuse."""
65
+ setup_langfuse(self.langfuse_config)
66
+ yield
67
+ shutdown_langfuse(self.langfuse_config)
68
+
58
69
  def _setup_cors(self):
59
70
  """Configure CORS middleware"""
60
71
  self.add_middleware(
@@ -1,9 +1,32 @@
1
1
  from pydantic_settings import BaseSettings
2
2
  from pydantic import Field, ConfigDict
3
3
  from pydantic import computed_field
4
+ from typing import Optional
4
5
  import logging
5
6
  import urllib
6
7
 
8
+ class LangfuseConfig(BaseSettings):
9
+ """Configuration for Langfuse observability.
10
+
11
+ Set these environment variables to enable tracing:
12
+ - LANGFUSE_SECRET_KEY: Your Langfuse secret key (sk-lf-...)
13
+ - LANGFUSE_PUBLIC_KEY: Your Langfuse public key (pk-lf-...)
14
+ - LANGFUSE_BASE_URL: Langfuse server URL (default: https://cloud.langfuse.com)
15
+ """
16
+ model_config = ConfigDict(extra="allow", env_file=[".env", ".env.secret"], env_file_encoding="utf-8")
17
+
18
+ langfuse_secret_key: Optional[str] = Field(default=None)
19
+ langfuse_public_key: Optional[str] = Field(default=None)
20
+ langfuse_base_url: str = Field(default="https://cloud.langfuse.com")
21
+ langfuse_enabled: bool = Field(default=True, description="Enable/disable Langfuse tracing")
22
+
23
+ @computed_field
24
+ @property
25
+ def is_configured(self) -> bool:
26
+ """Check if Langfuse credentials are configured"""
27
+ return bool(self.langfuse_secret_key and self.langfuse_public_key and self.langfuse_enabled)
28
+
29
+
7
30
  class AssistantExtensionConfig(BaseSettings):
8
31
  model_config = ConfigDict(extra="allow", env_file=[".env", ".env.secret"], env_file_encoding="utf-8")
9
32
 
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  from fastapi import APIRouter, FastAPI
4
4
  import os
5
5
  from fastapi.concurrency import asynccontextmanager
6
- from contentgrid_assistant_api.config import DatabaseConfig, AssistantExtensionConfig
6
+ from contentgrid_assistant_api.config import DatabaseConfig, AssistantExtensionConfig, LangfuseConfig
7
7
  from contentgrid_assistant_api.dependencies import DependencyResolver
8
8
  from contentgrid_assistant_api.routers.thread_router import HALLinkFor, generate_agent_thread_router
9
9
  from contentgrid_assistant_api.types.agents import Agent, AgentHomeResponse
@@ -16,10 +16,18 @@ def exit_uvicorn():
16
16
  os.kill(os.getppid(), signal.SIGINT)
17
17
 
18
18
 
19
- def generate_agent_home_router(agent : Agent, extension_config: AssistantExtensionConfig, database_config: DatabaseConfig) -> APIRouter:
19
+ def generate_agent_home_router(
20
+ agent: Agent,
21
+ extension_config: AssistantExtensionConfig,
22
+ database_config: DatabaseConfig,
23
+ langfuse_config: LangfuseConfig | None = None
24
+ ) -> APIRouter:
20
25
  if database_config.pg_dbname == database_config.__class__.model_fields["pg_dbname"].default:
21
26
  # Check if the pg_dbname is still the default, if yes use the agent name
22
27
  database_config.pg_dbname = agent.name
28
+
29
+ # Use provided langfuse_config or create default
30
+ langfuse_cfg = langfuse_config or LangfuseConfig()
23
31
 
24
32
  dep_resolver = DependencyResolver(agent=agent, db_config=database_config)
25
33
 
@@ -35,7 +43,13 @@ def generate_agent_home_router(agent : Agent, extension_config: AssistantExtensi
35
43
 
36
44
 
37
45
  router = APIRouter(lifespan=lifespan, tags=[agent.name])
38
- router.include_router(generate_agent_thread_router(dep_resolver, extension_config, tags=[agent.name]))
46
+ router.include_router(generate_agent_thread_router(
47
+ dep_resolver,
48
+ extension_config,
49
+ langfuse_config=langfuse_cfg,
50
+ agent_name=agent.name,
51
+ tags=[agent.name]
52
+ ))
39
53
 
40
54
  @router.get("/", response_model=AgentHomeResponse, response_model_exclude_unset=True)
41
55
  def get_agent_home(origin: Optional[HttpUrl] = None):
@@ -6,10 +6,11 @@ from typing import Annotated, AsyncGenerator, List, Union, Optional
6
6
  import typing
7
7
  import uuid
8
8
  from enum import Enum
9
+ from contentgrid_assistant_api.tracing import _create_langfuse_config
9
10
  from langgraph.graph.state import CompiledStateGraph
10
11
  from fastapi import APIRouter, BackgroundTasks, File, Form, Request, UploadFile, status
11
12
  from fastapi.params import Depends
12
- from contentgrid_assistant_api.config import AssistantExtensionConfig
13
+ from contentgrid_assistant_api.config import AssistantExtensionConfig, LangfuseConfig
13
14
  from fastapi.responses import StreamingResponse
14
15
  from contentgrid_assistant_api.db.repositories.thread_repository import ThreadRepository
15
16
  from contentgrid_assistant_api.db.types.message import HALHumanMessage, HALAIMessage, HALSystemMessage, HALToolMessage
@@ -20,14 +21,20 @@ from contentgrid_extension_helpers.responses.hal import FastAPIHALCollection, HA
20
21
  from langchain_core.messages import HumanMessage, SystemMessage, AIMessage, BaseMessage, ToolMessage
21
22
  from fastapi import HTTPException
22
23
 
23
-
24
24
  # ContentBlocks
25
25
  from langchain_core.messages.content import create_image_block, create_file_block, create_audio_block, create_text_block, ImageContentBlock, AudioContentBlock, FileContentBlock, TextContentBlock
26
26
  import logging
27
27
 
28
28
  from contentgrid_assistant_api.types.context import DefaultThreadContext
29
29
 
30
- def generate_agent_message_router(dep_resolver: DependencyResolver, extension_config: AssistantExtensionConfig, tags: Optional[List[str | Enum]]=None) -> APIRouter:
30
+
31
+ def generate_agent_message_router(
32
+ dep_resolver: DependencyResolver,
33
+ extension_config: AssistantExtensionConfig,
34
+ langfuse_config: LangfuseConfig,
35
+ agent_name: str,
36
+ tags: Optional[List[str | Enum]] = None
37
+ ) -> APIRouter:
31
38
  messagesrouter = APIRouter(prefix="/{thread_id}" + extension_config.routes_message_prefix, tags=tags or ["messages"])
32
39
 
33
40
  def convert_to_hal_message(message: BaseMessage, thread_id: uuid.UUID) -> Union[HALHumanMessage, HALAIMessage, HALSystemMessage, HALToolMessage]:
@@ -160,6 +167,9 @@ def generate_agent_message_router(dep_resolver: DependencyResolver, extension_co
160
167
  new_message = HumanMessage(content=content_blocks) # type: ignore
161
168
  messages = [new_message]
162
169
 
170
+ # Create Langfuse config with session_id, user_id, and tags for observability
171
+ lf_config = _create_langfuse_config(thread_context, user, agent_name, langfuse_config)
172
+
163
173
  if streaming:
164
174
  state = agent.get_state(config={"configurable" : thread_context}) #type: ignore
165
175
  nb_current_messages = 0
@@ -168,9 +178,15 @@ def generate_agent_message_router(dep_resolver: DependencyResolver, extension_co
168
178
 
169
179
  @typing.no_type_check
170
180
  async def generate_stream(current_message_index) -> AsyncGenerator[str, None]:
181
+ # Merge Langfuse config with LangGraph config
182
+ stream_config = {
183
+ "configurable": thread_context,
184
+ "recursion_limit": extension_config.graph_recursion_limit,
185
+ **lf_config
186
+ }
171
187
  for mode, chunk in agent.stream(
172
188
  {"messages": messages},
173
- {"configurable": thread_context, "recursion_limit": extension_config.graph_recursion_limit},
189
+ stream_config,
174
190
  context=thread_context,
175
191
  stream_mode=["values", "messages"]
176
192
  ):
@@ -214,11 +230,18 @@ def generate_agent_message_router(dep_resolver: DependencyResolver, extension_co
214
230
  }
215
231
  )
216
232
  else:
233
+ # Capture lf_config for closure
234
+ invoke_config = {
235
+ "configurable": thread_context,
236
+ "recursion_limit": extension_config.graph_recursion_limit,
237
+ **lf_config
238
+ }
239
+
217
240
  def process_agent_response():
218
241
  try:
219
242
  agent.invoke(
220
243
  {"messages": messages},
221
- {"configurable": thread_context, "recursion_limit": extension_config.graph_recursion_limit},
244
+ invoke_config,
222
245
  context=thread_context,
223
246
  )
224
247
  except Exception as e:
@@ -2,6 +2,7 @@
2
2
  from enum import Enum
3
3
  from typing import Annotated, List, Optional
4
4
  import uuid
5
+ from contentgrid_assistant_api.tracing import _create_langfuse_config_for_thread
5
6
  from fastapi import APIRouter, Depends, Query, status
6
7
  from pydantic import HttpUrl
7
8
 
@@ -15,13 +16,29 @@ from contentgrid_assistant_api.types.agents import AgentToolCollectionResponse,
15
16
  from contentgrid_assistant_api.types.context import DefaultThreadContext
16
17
  from langchain.messages import HumanMessage
17
18
  from langgraph.graph.state import CompiledStateGraph
18
- from contentgrid_assistant_api.config import AssistantExtensionConfig
19
+ from contentgrid_assistant_api.config import AssistantExtensionConfig, LangfuseConfig
20
+
21
+
22
+ def generate_agent_thread_router(
23
+ dep_resolver: DependencyResolver,
24
+ extension_config: AssistantExtensionConfig,
25
+ langfuse_config: LangfuseConfig | None = None,
26
+ agent_name: str = "agent",
27
+ tags: Optional[List[str | Enum]] = None
28
+ ):
29
+ # Use provided langfuse_config or create default
30
+ langfuse_cfg = langfuse_config or LangfuseConfig()
19
31
 
20
- def generate_agent_thread_router(dep_resolver: DependencyResolver, extension_config: AssistantExtensionConfig, tags: Optional[List[str | Enum]]=None):
21
32
  threadrouter = APIRouter(prefix=extension_config.routes_thread_prefix, tags=tags or ["threads"])
22
33
 
23
34
  threadrouter.include_router(
24
- generate_agent_message_router(dep_resolver, extension_config, tags=tags)
35
+ generate_agent_message_router(
36
+ dep_resolver,
37
+ extension_config,
38
+ langfuse_config=langfuse_cfg,
39
+ agent_name=agent_name,
40
+ tags=tags
41
+ )
25
42
  )
26
43
 
27
44
  @threadrouter.post("/", response_model=ThreadRead, status_code=status.HTTP_201_CREATED, response_model_exclude_none=True)
@@ -36,9 +53,17 @@ def generate_agent_thread_router(dep_resolver: DependencyResolver, extension_con
36
53
  thread_id = uuid.uuid4()
37
54
  messages = [HumanMessage(content=extension_config.opening_message)]
38
55
  context = dep_resolver.agent.thread_context(thread_id=str(thread_id), user=user, origin=origin)
56
+
57
+ # Create Langfuse config for thread creation tracing
58
+ lf_config = _create_langfuse_config_for_thread(str(thread_id), user, agent_name, langfuse_cfg, extra_tags=["create-thread"])
59
+ invoke_config = {
60
+ "configurable": context,
61
+ **lf_config
62
+ }
63
+
39
64
  agent.invoke(
40
65
  {"messages": messages},
41
- {"configurable": context}, #type: ignore
66
+ invoke_config, #type: ignore
42
67
  context=context, #type: ignore
43
68
  )
44
69
 
@@ -0,0 +1,67 @@
1
+
2
+ import logging
3
+ from contentgrid_assistant_api.config import LangfuseConfig
4
+ from contentgrid_assistant_api.types.context import ContentGridUser, DefaultThreadContext
5
+
6
+
7
+ def setup_langfuse(langfuse_config: LangfuseConfig) -> None:
8
+ """Initialize the Langfuse observability client."""
9
+ if langfuse_config.is_configured:
10
+ from langfuse import Langfuse
11
+ Langfuse(
12
+ public_key=langfuse_config.langfuse_public_key,
13
+ secret_key=langfuse_config.langfuse_secret_key,
14
+ base_url=langfuse_config.langfuse_base_url,
15
+ )
16
+ logging.info("Langfuse observability initialized successfully")
17
+ else:
18
+ logging.info("Langfuse not configured - tracing disabled. Set LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY to enable.")
19
+
20
+
21
+ def shutdown_langfuse(langfuse_config: LangfuseConfig) -> None:
22
+ """Flush and shut down the Langfuse client."""
23
+ if langfuse_config.is_configured:
24
+ from langfuse import get_client
25
+ get_client().shutdown()
26
+ logging.info("Langfuse client shutdown complete")
27
+
28
+
29
+ def _create_langfuse_config_for_thread(
30
+ thread_id: str,
31
+ user: ContentGridUser,
32
+ agent_name: str,
33
+ langfuse_config: LangfuseConfig,
34
+ extra_tags: list[str] | None = None
35
+ ) -> dict:
36
+ """Create LangChain config with Langfuse callback handler and metadata.
37
+
38
+ Per Langfuse best practices:
39
+ - session_id: Groups conversation messages together (using thread_id)
40
+ - user_id: Enables user filtering and cost attribution
41
+ - tags: Per-feature analytics (using agent name)
42
+ """
43
+ config: dict = {}
44
+
45
+ if langfuse_config.is_configured:
46
+ try:
47
+ from langfuse.langchain import CallbackHandler
48
+ langfuse_handler = CallbackHandler()
49
+ config["callbacks"] = [langfuse_handler]
50
+ config["metadata"] = {
51
+ "langfuse_session_id": thread_id,
52
+ "langfuse_user_id": user.sub,
53
+ "langfuse_tags": [agent_name] + (extra_tags or [])
54
+ }
55
+ except ImportError:
56
+ logging.warning("Langfuse not installed, tracing disabled")
57
+
58
+ return config
59
+
60
+ def _create_langfuse_config(
61
+ thread_context: DefaultThreadContext,
62
+ user: ContentGridUser,
63
+ agent_name: str,
64
+ langfuse_config: LangfuseConfig
65
+ ) -> dict:
66
+ """Create LangChain config with Langfuse callback handler for an existing thread."""
67
+ return _create_langfuse_config_for_thread(thread_context.thread_id, user, agent_name, langfuse_config)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: contentgrid-assistant-api
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: FastAPI wrapper for contentgrid assistants
5
5
  Author-email: Ranec Belpaire <ranec.belpaire@xenit.eu>
6
6
  License: Copyright 2024 Xenit Solutions
@@ -30,6 +30,7 @@ Requires-Dist: langchain>=1.2.3
30
30
  Requires-Dist: langchain_openai>=1.1.7
31
31
  Requires-Dist: langgraph>=1.0.5
32
32
  Requires-Dist: langgraph-checkpoint-postgres>=3.0.2
33
+ Requires-Dist: langfuse>=3.0.0
33
34
  Requires-Dist: python-dotenv>=1.1.1
34
35
  Requires-Dist: requests<3,>=2.32.5
35
36
  Requires-Dist: types-requests>=2.32.4
@@ -6,10 +6,13 @@ setup.py
6
6
  src/contentgrid_assistant_api/app.py
7
7
  src/contentgrid_assistant_api/config.py
8
8
  src/contentgrid_assistant_api/dependencies.py
9
+ src/contentgrid_assistant_api/tracing.py
9
10
  src/contentgrid_assistant_api.egg-info/PKG-INFO
10
11
  src/contentgrid_assistant_api.egg-info/SOURCES.txt
11
12
  src/contentgrid_assistant_api.egg-info/dependency_links.txt
12
13
  src/contentgrid_assistant_api.egg-info/requires.txt
14
+ src/contentgrid_assistant_api.egg-info/scm_file_list.json
15
+ src/contentgrid_assistant_api.egg-info/scm_version.json
13
16
  src/contentgrid_assistant_api.egg-info/top_level.txt
14
17
  src/contentgrid_assistant_api/db/repositories/thread_repository.py
15
18
  src/contentgrid_assistant_api/db/types/message.py
@@ -6,6 +6,7 @@ langchain>=1.2.3
6
6
  langchain_openai>=1.1.7
7
7
  langgraph>=1.0.5
8
8
  langgraph-checkpoint-postgres>=3.0.2
9
+ langfuse>=3.0.0
9
10
  python-dotenv>=1.1.1
10
11
  requests<3,>=2.32.5
11
12
  types-requests>=2.32.4
@@ -0,0 +1,24 @@
1
+ {
2
+ "files": [
3
+ "README.md",
4
+ "LICENSE",
5
+ "setup.py",
6
+ "pyproject.toml",
7
+ "pytest.ini",
8
+ "src/contentgrid_assistant_api/dependencies.py",
9
+ "src/contentgrid_assistant_api/config.py",
10
+ "src/contentgrid_assistant_api/app.py",
11
+ "src/contentgrid_assistant_api/tracing.py",
12
+ "src/contentgrid_assistant_api/db/repositories/thread_repository.py",
13
+ "src/contentgrid_assistant_api/db/types/message.py",
14
+ "src/contentgrid_assistant_api/db/types/thread.py",
15
+ "src/contentgrid_assistant_api/types/context.py",
16
+ "src/contentgrid_assistant_api/types/agents.py",
17
+ "src/contentgrid_assistant_api/routers/agent_home.py",
18
+ "src/contentgrid_assistant_api/routers/message_router.py",
19
+ "src/contentgrid_assistant_api/routers/thread_router.py",
20
+ "tests/test_tools_endpoint.py",
21
+ "tests/test_thread_access_control.py",
22
+ "tests/mock_agent.py"
23
+ ]
24
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.0.4",
3
+ "distance": 0,
4
+ "node": "ga52e3de53c38aa2efe3e7fd89c795fc33c7ac189",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-04-22"
8
+ }