feat(agent-runtime): 接入多服务商安全配置
This commit is contained in:
+63
-6
@@ -18,6 +18,46 @@ class RunStatus(models.TextChoices):
|
||||
CANCELLED = "cancelled", "已取消"
|
||||
|
||||
|
||||
class ProviderConnectionStatus(models.TextChoices):
|
||||
"""模型服务商连接状态。"""
|
||||
|
||||
CONNECTED = "connected", "已连接"
|
||||
FAILED = "failed", "需要重新验证"
|
||||
|
||||
|
||||
class ModelProviderConfig(UserOwnedModel):
|
||||
"""当前用户的模型服务商凭据与已验证模型快照。"""
|
||||
|
||||
provider_code = models.CharField("服务商编码", max_length=64)
|
||||
encrypted_api_key = models.TextField("加密 API Key")
|
||||
key_hint = models.CharField("密钥提示", max_length=12)
|
||||
status = models.CharField(
|
||||
"连接状态",
|
||||
max_length=20,
|
||||
choices=ProviderConnectionStatus,
|
||||
default=ProviderConnectionStatus.CONNECTED,
|
||||
)
|
||||
enabled = models.BooleanField("已启用", default=True)
|
||||
is_default = models.BooleanField("默认服务商", default=False)
|
||||
default_model_id = models.CharField("默认模型", max_length=160, blank=True)
|
||||
available_models = models.JSONField("可用模型快照", default=list)
|
||||
last_verified_at = models.DateTimeField("最近验证时间", null=True, blank=True)
|
||||
last_error_code = models.CharField("最近错误码", max_length=80, blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "模型服务商配置"
|
||||
verbose_name_plural = "模型服务商配置"
|
||||
ordering = ("provider_code",)
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=("owner", "provider_code"), name="provider_owner_code_uniq"
|
||||
)
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.owner} / {self.provider_code}"
|
||||
|
||||
|
||||
class AgentRun(UserOwnedModel):
|
||||
"""一次可审计的 Agent 运行;摘要字段不得保存敏感原文。"""
|
||||
|
||||
@@ -38,14 +78,18 @@ class AgentRun(UserOwnedModel):
|
||||
duration_ms = models.PositiveBigIntegerField("耗时毫秒", null=True, blank=True)
|
||||
input_tokens = models.PositiveBigIntegerField("输入 Token", null=True, blank=True)
|
||||
output_tokens = models.PositiveBigIntegerField("输出 Token", null=True, blank=True)
|
||||
estimated_cost = models.DecimalField("估算费用", max_digits=12, decimal_places=6, null=True, blank=True)
|
||||
estimated_cost = models.DecimalField(
|
||||
"估算费用", max_digits=12, decimal_places=6, null=True, blank=True
|
||||
)
|
||||
error_code = models.CharField("错误码", max_length=80, blank=True)
|
||||
error_summary = models.TextField("错误摘要", blank=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ("-created_at",)
|
||||
indexes = [models.Index(fields=("owner", "created_at"), name="run_owner_created_idx")]
|
||||
constraints = [models.CheckConstraint(condition=Q(lock_version__gte=0), name="run_lock_nonnegative")]
|
||||
constraints = [
|
||||
models.CheckConstraint(condition=Q(lock_version__gte=0), name="run_lock_nonnegative")
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
@@ -64,7 +108,14 @@ class AgentRunEvent(models.Model):
|
||||
|
||||
class Meta:
|
||||
ordering = ("sequence",)
|
||||
constraints = [models.UniqueConstraint(fields=("run", "sequence"), name="event_run_sequence_uniq")]
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=("run", "sequence"), name="event_run_sequence_uniq")
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
"""使用运行标题和序号提供稳定、可读的管理端标识。"""
|
||||
|
||||
return f"{self.run} / 事件 {self.sequence}"
|
||||
|
||||
|
||||
class ToolCallStatus(models.TextChoices):
|
||||
@@ -81,7 +132,9 @@ class ToolCall(TimeStampedModel):
|
||||
tool_name = models.CharField("工具名称", max_length=100)
|
||||
tool_version = models.CharField("工具版本", max_length=40, blank=True)
|
||||
idempotency_key = models.CharField("幂等键", max_length=128, blank=True)
|
||||
status = models.CharField("状态", max_length=20, choices=ToolCallStatus, default=ToolCallStatus.STARTED)
|
||||
status = models.CharField(
|
||||
"状态", max_length=20, choices=ToolCallStatus, default=ToolCallStatus.STARTED
|
||||
)
|
||||
arguments_summary = models.JSONField("参数摘要", default=dict)
|
||||
result_summary = models.JSONField("结果摘要", null=True, blank=True)
|
||||
error_code = models.CharField("错误码", max_length=80, blank=True)
|
||||
@@ -117,7 +170,9 @@ class HumanApproval(TimeStampedModel):
|
||||
run = models.ForeignKey(AgentRun, on_delete=models.PROTECT, related_name="approvals")
|
||||
request_key = models.CharField("请求键", max_length=128)
|
||||
approval_type = models.CharField("确认类型", max_length=64)
|
||||
status = models.CharField("状态", max_length=20, choices=ApprovalStatus, default=ApprovalStatus.PENDING)
|
||||
status = models.CharField(
|
||||
"状态", max_length=20, choices=ApprovalStatus, default=ApprovalStatus.PENDING
|
||||
)
|
||||
request_summary = models.JSONField("请求摘要", default=dict)
|
||||
decision_summary = models.JSONField("处理摘要", null=True, blank=True)
|
||||
requested_at = models.DateTimeField("请求时间")
|
||||
@@ -132,4 +187,6 @@ class HumanApproval(TimeStampedModel):
|
||||
|
||||
class Meta:
|
||||
indexes = [models.Index(fields=("status", "requested_at"), name="approval_status_time_idx")]
|
||||
constraints = [models.UniqueConstraint(fields=("run", "request_key"), name="approval_run_key_uniq")]
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=("run", "request_key"), name="approval_run_key_uniq")
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user