cls-agent-observability
给 OpenAI Agents SDK 应用接入腾讯云 CLS Agent 可观测。
一行代码初始化,业务代码零改动。
from cls_agent_observability import setup
setup() # 读环境变量即可
之后正常调用 Runner.run() / Runner.run_streamed(),Agent 的调用链、Token 用量、
工具调用、错误原因就会自动出现在 CLS 控制台,不需要在业务代码里写任何埋点。
目录
它能给你什么
接入后在 CLS 的 Agent 可观测里可以看到:
| 能力 | 说明 |
|---|---|
| 完整调用链 | 一次请求 → Agent 调用 → ReAct 轮次 → 模型调用 / 工具调用的父子关系 |
| 多轮会话聚合 | 同一个用户会话的多次请求归到同一个 Session,轮次号 t1 / t2 / t3 递增 |
| Token 与成本 | 每次模型调用的输入/输出/缓存命中 Token,以及每个 Agent 的汇总用量 |
| 失败可定位 | 限频(rate_limit)、超时(timeout)、鉴权失败(authentication_error)等分类错误,而不是一句笼统的报错 |
| 工具调用详情 | 工具名、入参、返回值、耗时,失败时带错误类型 |
| 多 Agent / Handoff | Agent 之间的转交关系,各 Agent 的开销分别归因 |
| 正文可选 | 输入输出消息按需采集,默认关闭(保护隐私与存储成本) |
设计上的几个取舍:
- 不侵入业务代码:完全基于 Agents SDK 自身的
TracingProcessor生命周期回调, 你不需要手写 span、不需要装饰器、不需要改函数签名。 - 不引入专有依赖:上报走 CLS 官方支持的标准 OTLP/HTTP,只依赖 OpenTelemetry 社区包。
- 不给你的应用添新故障点:转换层全程异常隔离,内部状态有内存上界, 上报在后台线程完成(详见对你的应用有多大影响)。
快速开始(5 分钟)
第 1 步:装包
pip install cls-agent-observability
中国大陆网络较慢时用国内镜像(任选其一):
# 清华 TUNA(推荐)
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple cls-agent-observability
# 阿里云
pip install -i https://mirrors.aliyun.com/pypi/simple/ cls-agent-observability
# 腾讯云(在腾讯云服务器上用这个最快)
pip install -i https://mirrors.cloud.tencent.com/pypi/simple/ cls-agent-observability
想长期生效,把镜像写进 pip 配置(只需做一次):
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn
用 uv / poetry / conda 的写法
# uv
uv add cls-agent-observability --default-index https://pypi.tuna.tsinghua.edu.cn/simple
# poetry
poetry source add --priority=primary tuna https://pypi.tuna.tsinghua.edu.cn/simple
poetry add cls-agent-observability
# conda 环境里仍用 pip 装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple cls-agent-observability
第 2 步:在 CLS 创建一个 Agent 可观测应用
日志主题不用手工建 —— 它由"应用接入"流程自动创建并关联。手工建的普通 Trace 主题不属于任何应用,控制台的调用链页面是按应用组织的,会找不到入口。
- 登录腾讯云 → 日志服务 CLS → 左侧 Agent 可观测 (直达:https://console.cloud.tencent.com/cls/agent/observe)
- 选一个地域(记住它,第 3 步的接入点要用同一个地域)
- 点 【应用接入】,按页面提示创建应用
- 在新建好的应用右侧点【编辑】,复制 Trace 日志主题 ID
(形如
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) - 准备一对访问密钥。建议用只有写入权限的子账号密钥,不要用主账号密钥 (API 密钥管理:https://console.cloud.tencent.com/cam/capi)
最容易踩的坑:
CLS_TOPIC_ID要填 Trace 日志主题 ID,不是应用 ID。 两者形态相似(都是 uuid),但应用 ID 只用于在控制台里定位应用,不作为配置项。 填错的表现是数据写不进去,而且报错不直观 —— 这是官方 FAQ 的头号排查项。
第 3 步:配置 4 个环境变量
# 接入点:把 <region> 换成你的地域,如 ap-guangzhou / ap-shanghai / ap-beijing
# 在腾讯云内网(CVM/TKE)用 .cls.tencentyun.com,走内网更快且不产生公网流量费
export CLS_ENDPOINT="ap-guangzhou.cls.tencentyun.com"
# 公网环境用:ap-guangzhou.cls.tencentcs.com
export CLS_TOPIC_ID="第 2 步复制的 Trace 日志主题 ID" # 不是应用 ID
export CLS_SECRET_ID="你的SecretId"
export CLS_SECRET_KEY="你的SecretKey"
接入点的地域必须和日志主题的地域一致,否则会报
topic not found。
第 4 步:加一行代码
在你的应用启动时、第一次调用 Runner.run() 之前:
from agents import Agent, Runner
from cls_agent_observability import setup
setup() # ← 就这一行
agent = Agent(name="我的助手", instructions="你是一个有用的助手。")
result = await Runner.run(agent, "你好")
print(result.final_output)
完成。去控制台看数据:Agent 可观测 → 点进第 2 步创建的应用 → 调用链 → 选包含测试请求的时间范围 → 打开最新一条 Trace。数据有几十秒的索引延迟。
建议第一次验证时跑一个带工具调用的请求,这样能一次性看到
entry / agent / step / chat / tool 完整的调用树,而不只是一个 chat。
第 5 步(重要):让多轮对话聚合成一个会话
上面这样每次请求都是一个独立会话。要把同一个用户的多轮对话串起来, 传一个稳定的会话 ID 进去:
from agents import RunConfig, Runner
result = await Runner.run(
agent,
user_message,
run_config=RunConfig(group_id=会话ID), # ← 你自己的会话标识
)
group_id 用什么值由你决定 —— 常见做法是浏览器 session id、聊天窗口 id、
或数据库里的 conversation id。只要同一个对话的多次请求传同一个值,
CLS 上就会归到同一个 Session,轮次号自动 t1 / t2 / t3 递增。
请传短的稳定标识(UUID、会话表主键等),不要把整段对话历史或序列化对象 当成
group_id。原因:session id 会写进每一条 span 的两个字段,超长值会 直接放大你的存储与流量成本;而且实测 CLS 的检索接口有约 12000 字符的查询长度 上限,超过后数据虽然存进去了,却再也无法按 session 筛出来。本 SDK 已做兜底:超过
max_session_id_length(默认 512)时会截断,并拼上原值 的 sha256 指纹(形如<前缀>~9ba3fb227507)。指纹保证不同会话不会被合并成 同一个,同一个原始值也始终映射到同一个结果(所以轮次号仍连续递增)。 首次发生截断时会打一条WARNING日志(只打一次,不刷屏)。
第 6 步(可选):应用退出时把缓冲区刷出去
上报是批量异步的,进程直接退出可能丢掉最后几条:
provider = setup()
try:
... # 你的应用主体
finally:
provider.force_flush()
provider.shutdown()
FastAPI 里可以挂到 lifespan:
from contextlib import asynccontextmanager
from fastapi import FastAPI
@asynccontextmanager
async def lifespan(app: FastAPI):
provider = setup()
yield
provider.force_flush()
provider.shutdown()
app = FastAPI(lifespan=lifespan)
工作原理
OpenAI Agents SDK 在运行过程中会产生自己的 Trace/Span(这是它内置的能力)。
本 SDK 注册一个 TracingProcessor,监听这些事件并翻译成符合 CLS Agent Trace
协议的 OpenTelemetry Span,再通过标准 OTLP/HTTP 发到你的 CLS 日志主题。
你的代码 Agents SDK 内部 本 SDK CLS
──────── ─────────────── ────── ───
Runner.run() ──────► trace 开始
├─ agent span ──────► 监听并翻译
├─ turn span (加上 session/turn/
├─ generation span token/错误分类等
└─ function span 协议字段)
trace 结束 │
▼
OpenTelemetry Span
│
BatchSpanProcessor(后台线程)
│
OTLP/HTTP ──────────────► 日志主题
映射关系:
| Agents SDK 的 span | CLS 协议的 span kind | span 名称 |
|---|---|---|
| trace 本身 | entry |
enter_application |
| Agent 调用 | agent |
invoke_agent <Agent名> |
| ReAct 轮次 | step |
react round_<N> |
| 模型调用 | chat |
chat <模型名> |
| 工具调用 | tool |
execute_tool <工具名> |
为什么不需要你埋点:这些 span 是 Agents SDK 自己产生的,我们只是"翻译", 所以你的业务代码不用做任何配合。
完整配置项
两种配置方式,代码传参优先级高于环境变量:
from cls_agent_observability import CLSConfig, setup
setup(CLSConfig(
endpoint="ap-guangzhou.cls.tencentyun.com",
topic_id="...",
secret_id="...",
secret_key="...",
))
必填
| 配置项 | 环境变量 | 说明 |
|---|---|---|
endpoint |
CLS_ENDPOINT |
CLS 接入点域名(不带 https://),地域需与主题一致 |
topic_id |
CLS_TOPIC_ID |
日志主题 ID |
secret_id |
CLS_SECRET_ID |
访问密钥 ID |
secret_key |
CLS_SECRET_KEY |
访问密钥 Key |
缺任何一项,setup() 会抛 RuntimeError 并明确指出缺哪个(不会静默失败)。
服务标识
| 配置项 | 环境变量 | 默认 | 说明 |
|---|---|---|---|
service_name |
CLS_SERVICE_NAME |
openai-agents-app |
服务名。CLS 上是独立索引列,可直接 service:"xxx" 检索 |
host_name |
CLS_HOST_NAME |
本机 hostname | 主机名。K8s 上建议注入 Pod 名 |
deployment_environment |
CLS_DEPLOYMENT_ENVIRONMENT |
不上报 | 运行环境,如 production / staging |
正文采集(隐私与成本相关)
| 配置项 | 环境变量 | 默认 | 说明 |
|---|---|---|---|
content_mode |
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT |
off |
off / truncate / full |
content_max_length |
CLS_CONTENT_MAX_LENGTH |
8192 |
truncate 模式下单字段最大字符数 |
content_total_max_length |
CLS_CONTENT_TOTAL_MAX_LENGTH |
1048576 |
单条 span 全部正文合计上限 |
input_messages_mode |
CLS_INPUT_MESSAGES_MODE |
full |
full 自包含;delta 只报增量,存储从 O(n²) 降到 O(n) |
默认关闭正文采集是有意的。开启后
gen_ai.output.messages会包含模型的 思维链(reasoning),体积常是最终答案的数倍,且可能暴露内部推理过程。 关闭正文不影响调用链、耗时、状态和 Token 用量的上报。
truncate只限制长度,不等于脱敏 —— 手机号、账号、密钥若出现在提示词或 工具返回值里仍会被完整上报。涉敏场景需要你自己在工具返回值和提示词层面处理。
用户身份
| 配置项 | 环境变量 | 说明 |
|---|---|---|
user_id |
CLS_USER_ID |
用户标识。仅适用于 CLI / 单用户场景 |
user_name |
CLS_USER_NAME |
用户展示名,与 user_id 是两个独立字段 |
Web 服务里用户是每请求变化的,不要用静态配置,改用按请求注入(见下一节)。 两者都不设时不上报该字段 —— 本 SDK 不会用主机名之类的东西伪造用户身份。
行为与资源上界
| 配置项 | 环境变量 | 默认 | 说明 |
|---|---|---|---|
replace_existing_processors |
— | True |
True 时 CLS 成为唯一上报目标;False 则与你已有的 processor 并存 |
mirror_identity_in_resource |
CLS_MIRROR_IDENTITY_IN_RESOURCE |
False |
在 resource 内额外镜像一份服务/主机标识 |
max_tracked_sessions |
— | 10000 |
同时跟踪的会话数上界,超出按 LRU 淘汰 |
max_inflight_traces |
— | 2000 |
进行中 trace 数上界,防止异常路径下的内存泄漏 |
max_session_id_length |
— | 512 |
group_id 长度上限,超出会截断并附指纹(见下) |
debug |
CLS_DEBUG |
False |
打印内部调试日志(不含密钥与正文) |
关于 replace_existing_processors:默认 True,意味着 Agents SDK 自带的
"上报到 OpenAI 平台"会被替换掉 —— 通常这正是你想要的(数据不外流、也不会因为
没配 OPENAI_API_KEY 而反复打告警日志)。如果你已经接了别的可观测后端并希望
同时保留,改成 False:
setup(CLSConfig(replace_existing_processors=False))
自定义字段:三种注入方式
按"这个值多久变一次"来选,选错会导致数据不对或性能浪费。
方式一:每请求变化的值 → RunConfig.trace_metadata
用户 ID、租户 ID、请求来源这类每次请求都不同的值:
from agents import RunConfig, Runner
result = await Runner.run(
agent,
user_message,
run_config=RunConfig(
group_id=会话ID,
trace_metadata={
"gen_ai.user.id": "u-10086", # 用户标识
"gen_ai.user.name": "张三", # 用户展示名
},
),
)
目前支持通过 trace_metadata 注入的键(每个都接受多种别名,写哪个都行):
| 协议字段 | 可用的键名 |
|---|---|
gen_ai.user.id |
gen_ai.user.id / user_id / user.id |
gen_ai.user.name |
gen_ai.user.name / user_name / user.name |
方式二:进程级不变的业务维度 → extra_span_attributes
租户、部署单元、业务线这类整个进程生命周期都不变的值。会加到每一条 span 上:
setup(CLSConfig(
extra_span_attributes={
"agent.myapp.tenant_id": "acme-corp",
"agent.myapp.region": "cn-south",
},
))
命名建议用 agent.<你的产品名>.<字段> —— CLS Agent Trace 协议为厂商扩展保留了
agent.* 命名空间,这样不会和协议自身的字段冲突。
检索方式:attribute.agent.myapp.tenant_id:"acme-corp"
方式三:服务/环境级标识 → extra_resource_attributes
服务版本、命名空间、集群名这类描述"这个进程是谁"的值:
setup(CLSConfig(
service_name="order-agent",
host_name="pod-order-agent-7f9c",
deployment_environment="production",
extra_resource_attributes={
"service.version": "1.4.2",
"service.namespace": "commerce",
},
))
检索方式:service:"order-agent"、resource.service.version:"1.4.2"
一个实测结论:CLS 的 OTLP 接入层会把
service.name/host.name提取成顶层 独立列(service/host),其余 resource 属性留在resourceJSON 内。 顶层列有独立索引、检索更快,所以高频过滤的维度优先放service_name。 如果你的下游系统需要从resource里读到服务标识,开mirror_identity_in_resource=True会额外镜像一份agent.service.name/agent.host.name。
三种方式怎么选
| 值的变化频率 | 用哪个 | 例子 |
|---|---|---|
| 每次请求都不同 | RunConfig.trace_metadata |
用户 ID、请求 ID |
| 进程启动后不变,需按 span 过滤 | extra_span_attributes |
租户、业务线 |
| 描述服务/环境本身 | extra_resource_attributes |
版本、命名空间、集群 |
不要把每请求变化的值放进 extra_*(那是 setup() 时固定的,放进去所有请求都是同一个值)。
部署:Docker / 虚拟机 / 物理机
三种方式的差别只在环境变量怎么传,代码完全一样。
通用原则:密钥必须运行时注入,不能写进代码、Dockerfile、镜像层或提交到 Git。
Docker
FROM python:3.12-slim
WORKDIR /app
# 用国内镜像加速(构建在境内时)
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "-m", "your_app"]
运行时注入(不要 ENV CLS_SECRET_KEY=...):
docker run -d \
-e CLS_ENDPOINT="ap-guangzhou.cls.tencentyun.com" \
-e CLS_TOPIC_ID="..." \
-e CLS_SECRET_ID="..." \
-e CLS_SECRET_KEY="..." \
-e CLS_SERVICE_NAME="order-agent" \
-e CLS_DEPLOYMENT_ENVIRONMENT="production" \
your-image:tag
docker-compose:
services:
app:
image: your-image:tag
env_file: .env # .env 要加进 .gitignore
environment:
CLS_SERVICE_NAME: order-agent
CLS_DEPLOYMENT_ENVIRONMENT: production
Kubernetes / TKE
env:
- name: CLS_ENDPOINT
value: "ap-guangzhou.cls.tencentyun.com" # 内网接入点
- name: CLS_TOPIC_ID
value: "你的主题ID"
- name: CLS_SERVICE_NAME
value: "order-agent"
- name: CLS_DEPLOYMENT_ENVIRONMENT
value: "production"
- name: CLS_HOST_NAME # 注入 Pod 名,便于定位副本
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: CLS_SECRET_ID
valueFrom:
secretKeyRef: { name: cls-credentials, key: secret-id }
- name: CLS_SECRET_KEY
valueFrom:
secretKeyRef: { name: cls-credentials, key: secret-key }
多副本注意:轮次计数器保存在进程内存里。如果同一个会话的不同请求被 负载均衡到不同 Pod,Session 仍能正确聚合(因为用的是你传的
group_id), 但轮次号可能不连续。需要严格连续的轮次号时,请在网关层做会话亲和性 (sticky session),或自行在应用侧管理轮次并通过group_id编码。
虚拟机 / 物理机(systemd)
# /etc/systemd/system/my-agent.service
[Unit]
Description=My Agent
After=network-online.target
[Service]
User=appuser
WorkingDirectory=/opt/my-agent
# 密钥放独立文件,权限设为 600,只有服务账号可读
EnvironmentFile=/etc/my-agent/cls.env
ExecStart=/opt/my-agent/.venv/bin/python -m your_app
Restart=always
[Install]
WantedBy=multi-user.target
# /etc/my-agent/cls.env (chmod 600)
CLS_ENDPOINT=ap-guangzhou.cls.tencentyun.com
CLS_TOPIC_ID=...
CLS_SECRET_ID=...
CLS_SECRET_KEY=...
CLS_SERVICE_NAME=order-agent
CLS_DEPLOYMENT_ENVIRONMENT=production
sudo chmod 600 /etc/my-agent/cls.env
sudo systemctl daemon-reload && sudo systemctl enable --now my-agent
裸机上临时跑(开发调试)也可以用 .env 文件 + python-dotenv:
from dotenv import load_dotenv
load_dotenv() # 必须在 setup() 之前
from cls_agent_observability import setup
setup()
注意:如果你的应用用 pydantic-settings 读
.env,它不会把值写进os.environ,本 SDK 的环境变量回落读不到。这种情况请把配置项声明进你自己的 Settings,然后显式传给CLSConfig(...)。
对你的应用有多大影响
可观测组件不该成为新的故障点。这里是实测数据和具体做法。
性能
实测(scripts/benchmark_overhead.py,每请求约 11 个 span,含 3 轮 ReAct 与工具调用):
| 场景 | 每请求净开销 | 折算每 span |
|---|---|---|
content_mode=off(生产默认) |
≈ 295 μs | ≈ 27 μs |
content_mode=truncate |
≈ 372 μs | ≈ 34 μs |
真实 Agent 请求含模型调用,端到端通常在 1000 ms 量级,转换层占比约 0.03%。
不阻塞请求路径
上报由 OpenTelemetry 的 BatchSpanProcessor 在后台线程批量完成。
CLS 不可用、网络抖动、鉴权失败都不会阻塞你的业务请求 —— 最坏情况是这段观测数据丢失。
异常隔离
TracingProcessor 的四个生命周期入口全部包了异常隔离层:内部出错只记一条
warning 日志(含堆栈,不含正文与密钥),不会把异常抛进你的 Agent 执行流。
对上游 span 类型采用鸭子类型分发,运行期不 import Agents SDK 的内部类 —— 上游重命名或移除某个类型时,你的应用不会在启动时崩掉。
内存有界
内部状态全部有上界,不会随运行时长无限增长:
- 会话状态(轮次计数等)上界
max_tracked_sessions(默认 10000),超出按 LRU 淘汰 - 进行中的 trace 上界
max_inflight_traces(默认 2000),防止异常路径下泄漏
实测回放 1000 个请求后转换层常驻 28 KiB,进行中 trace 残留 0 条。
配置校验
setup() 时校验必填项,缺失直接抛 RuntimeError 并指出缺哪一项 ——
宁可启动时明确失败,也不要上线后才发现一直没数据。
兼容性
Python
3.10 / 3.11 / 3.12 / 3.13 均实测通过(scripts/check_python_compat.py)。
openai-agents
依赖声明 >=0.15,<1.0。实测通过的版本:0.15.0 / 0.17.0 / 0.18.0 / 0.19.0 / 0.20.0 / 0.21.0 / 0.22.0。
由于对上游 span 类型使用鸭子类型分发、不在运行期 import 其内部类, 小版本升级通常无需等本 SDK 跟进。
与其他可观测方案共存
已经接了别的 OpenTelemetry 后端时,两种做法:
# 做法一:并存(保留你已有的 processor)
setup(CLSConfig(replace_existing_processors=False))
# 做法二:复用你已有的 TracerProvider(这样 Resource、采样器等配置统一)
setup(CLSConfig(...), provider=your_existing_tracer_provider)
排障
控制台看不到数据
按顺序排查:
-
setup()是否在第一次Runner.run()之前调用?之前产生的 trace 不会补采。 -
CLS_TOPIC_ID是不是误填成了应用 ID?要填的是应用【编辑】里的 Trace 日志主题 ID。两者都是 uuid,最容易搞混,这是头号原因。 -
地域是否匹配?
CLS_ENDPOINT的地域必须与日志主题的地域一致,否则报topic not found。 -
内网/外网域名选对了吗?腾讯云内网用
.cls.tencentyun.com,公网环境用.cls.tencentcs.com。选错会连不上。 -
等够时间了吗?CLS 索引有几十秒延迟。
-
是否在应用内的调用链页面查看?普通日志检索页面看的是原始日志, 调用链视图在 Agent 可观测 → 进入应用 → 调用链。
-
进程是否过早退出?短脚本请在结束前
provider.force_flush()。 -
开 debug 看日志:
CLS_DEBUG=true,或import logging logging.getLogger("cls_agent_observability").setLevel(logging.DEBUG)
-
子账号权限:需要
cls:PushLog(写入)权限。401/403 通常是密钥或权限问题。
多轮对话没聚合成一个 Session
没传 RunConfig(group_id=...)。不传时每次请求都是独立会话(这是与 Agents SDK
一致的兜底行为)。见第 5 步。
看不到输入输出消息
正文采集默认关闭。设 OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=truncate。
请先读正文采集一节的隐私提示。
Token 或模型名缺失
这些值来自模型服务的返回结果。部分 OpenAI 兼容服务不返回 usage 或响应模型名,
此时无法凭空推算。请确认你的模型服务是否返回了这些字段。
出现重复的调用链
检查是否同时启用了多个上报路径(例如既调了 setup() 又自己注册了
TracingProcessor)。对照验证之外,建议同一个 Agent 实例只保留一条上报路径。
日志里出现 "OPENAI_API_KEY is not set, skipping trace export"
这是 Agents SDK 自带的"上报到 OpenAI 平台"processor 在报警,与本 SDK 无关。
把 replace_existing_processors 保持默认 True 即可(CLS 成为唯一上报目标)。
许可证
MIT
Metadata
Release files for cls-agent-observability 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cls_agent_observability-0.1.0.tar.gz | 53.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cls_agent_observability-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 100.9 kB
Release files / cls_agent_observability-0.1.0.tar.gz
| Download URL | cls_agent_observability-0.1.0.tar.gz |
|---|---|
| Size | 53.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1d60f645588f3dc0c80ae761d30452d0837029461715d9353f39998281dc9dfd
|
|
BLAKE2b-256 checksum How to use checksums |
f5814f53c9799ce1bac24878496f02f4a2f56281f680c93d61dca31d2bc8d79e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / cls_agent_observability-0.1.0-py3-none-any.whl
| Download URL | cls_agent_observability-0.1.0-py3-none-any.whl |
|---|---|
| Size | 47.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
031073b644618ccec3d37e7f77876e469c9ab420a3deb850be20a5b4620fc3f1
|
|
BLAKE2b-256 checksum How to use checksums |
3556aab4e50625b5bdfc4b194c8126077457572b33258dcd03bda6a1fa8f1fba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|