diff --git a/agent.py b/agent.py index 28694aa..29179e5 100644 --- a/agent.py +++ b/agent.py @@ -42,6 +42,65 @@ APPROVAL_PHRASE = "I_APPROVE_THE_LISTED_STEPS" OUTPUT_ROOT = "outputs/integrations" SECRET_WORDS = ("secret", "token", "password", "passwd", "apikey", "api_key", "authorization", "bearer") +_BOUNDED_OBJECT_SCHEMA: dict[str, Any] = { + "type": "object", + "maxProperties": 200, + "additionalProperties": True, +} +_BOUNDED_OBJECT_ARRAY_SCHEMA: dict[str, Any] = { + "type": "array", + "maxItems": 50, + "items": _BOUNDED_OBJECT_SCHEMA, +} +_INTEGRATION_REQUIREMENTS_SCHEMA: dict[str, Any] = { + "type": "object", + "required": ["integration_id", "title", "systems", "success_criteria"], + "additionalProperties": True, + "properties": { + "integration_id": {"type": "string", "pattern": "^[a-z][a-z0-9-]{2,63}$"}, + "title": {"type": "string", "minLength": 1, "maxLength": 160}, + "systems": {"type": "array", "minItems": 1, "maxItems": 12, "items": _BOUNDED_OBJECT_SCHEMA}, + "auth_methods": {"type": "array", "maxItems": 12, "items": _BOUNDED_OBJECT_SCHEMA}, + "data_contracts": {"type": "array", "maxItems": 20, "items": _BOUNDED_OBJECT_SCHEMA}, + "rate_limits": {"type": "array", "maxItems": 20, "items": _BOUNDED_OBJECT_SCHEMA}, + "environments": {"type": "array", "maxItems": 12, "items": _BOUNDED_OBJECT_SCHEMA}, + "success_criteria": {"type": "array", "minItems": 1, "maxItems": 20, "items": _BOUNDED_OBJECT_SCHEMA}, + "external_host_allowlist": {"type": "array", "maxItems": 50, "items": {"type": "string", "maxLength": 253}}, + "repository_write_allowlist": {"type": "array", "maxItems": 20, "items": {"type": "string", "maxLength": 201}}, + "dry_run": {"type": "boolean", "default": True}, + }, +} +_DESIGN_INPUT_SCHEMA: dict[str, Any] = { + "type": "object", + "required": ["request"], + "additionalProperties": False, + "properties": {"request": {"type": "object", "required": ["requirements"], "additionalProperties": False, "properties": {"requirements": _INTEGRATION_REQUIREMENTS_SCHEMA, "create_artifacts": {"type": "boolean", "default": True}, "dry_run": {"type": "boolean", "default": True}}}}, +} +_GENERATE_INPUT_SCHEMA: dict[str, Any] = { + "type": "object", + "required": ["request"], + "additionalProperties": False, + "properties": {"request": {"type": "object", "required": ["requirements"], "additionalProperties": False, "properties": {"requirements": _INTEGRATION_REQUIREMENTS_SCHEMA, "connector_language": {"type": "string", "enum": ["python", "typescript"], "default": "python"}, "include_tests": {"type": "boolean", "default": True}, "dry_run": {"type": "boolean", "default": True}, "external_host_allowlist": {"type": "array", "maxItems": 50, "items": {"type": "string", "maxLength": 253}}, "repository_write_allowlist": {"type": "array", "maxItems": 20, "items": {"type": "string", "maxLength": 201}}}}}, +} +_VALIDATE_INPUT_SCHEMA: dict[str, Any] = { + "type": "object", + "required": ["request"], + "additionalProperties": False, + "properties": {"request": {"type": "object", "required": ["integration_id", "contracts"], "additionalProperties": False, "properties": {"integration_id": {"type": "string", "pattern": "^[a-z][a-z0-9-]{2,63}$"}, "contracts": {"type": "array", "minItems": 1, "maxItems": 20, "items": _BOUNDED_OBJECT_SCHEMA}, "fail_on_drift": {"type": "boolean", "default": True}, "dry_run": {"type": "boolean", "default": True}}}}, +} +_ACCEPTANCE_INPUT_SCHEMA: dict[str, Any] = { + "type": "object", + "required": ["request"], + "additionalProperties": False, + "properties": {"request": {"type": "object", "required": ["integration_id"], "additionalProperties": False, "properties": {"integration_id": {"type": "string", "pattern": "^[a-z][a-z0-9-]{2,63}$"}, "endpoint_tests": _BOUNDED_OBJECT_ARRAY_SCHEMA, "contract_fixtures": _BOUNDED_OBJECT_ARRAY_SCHEMA, "external_host_allowlist": {"type": "array", "maxItems": 50, "items": {"type": "string", "maxLength": 253}}, "allow_network": {"type": "boolean", "default": False}, "max_retries": {"type": "integer", "minimum": 0, "maximum": 3, "default": 1}, "timeout_seconds": {"type": "number", "minimum": 1.0, "maximum": 30.0, "default": 8.0}, "dry_run": {"type": "boolean", "default": True}}}}, +} +_HANDOFF_INPUT_SCHEMA: dict[str, Any] = { + "type": "object", + "required": ["request"], + "additionalProperties": False, + "properties": {"request": {"type": "object", "required": ["integration_id", "title", "rollout_steps", "rollback_steps", "monitoring_checks"], "additionalProperties": False, "properties": {"integration_id": {"type": "string", "pattern": "^[a-z][a-z0-9-]{2,63}$"}, "title": {"type": "string", "minLength": 1, "maxLength": 160}, "rollout_steps": {"type": "array", "minItems": 1, "maxItems": 30, "items": {"type": "string", "maxLength": 8000}}, "rollback_steps": {"type": "array", "minItems": 1, "maxItems": 30, "items": {"type": "string", "maxLength": 8000}}, "monitoring_checks": {"type": "array", "minItems": 1, "maxItems": 30, "items": {"type": "string", "maxLength": 8000}}, "operator_notes": _BOUNDED_OBJECT_ARRAY_SCHEMA, "delivery_actions": {"type": "array", "maxItems": 20, "items": {"type": "string", "maxLength": 8000}}, "plan_digest": {"type": ["string", "null"], "maxLength": 128}, "approval_phrase": {"type": ["string", "null"], "maxLength": 64}, "approve_delivery": {"type": "boolean", "default": False}, "dry_run": {"type": "boolean", "default": True}}}}, +} + class StrictModel(BaseModel): model_config = ConfigDict(extra="forbid", str_strip_whitespace=True)