Skip to content

[Feature]: Dynamic Policy Conditions - Time-Based, Cost-Aware, and Adaptive Agent Behavior #2615

@imran-siddique

Description

@imran-siddique

Package: agent-os-kernel

Problem Statement

Currently, AGT policies evaluate against static action properties known at policy authoring time (e.g., action.type == 'drop', action.tool == 'sql_executor'). This works well for content-based governance but falls short for runtime-dependent decisions like:

  • Time-based policies: Blocking expensive operations outside business hours
  • Resource-aware constraints: Enforcing cost budgets, API quotas, rate limits
  • Agent behavior adaptation: Automatic backoff during congestion, temporarily disabling tools when budgets are depleted
  • Context-sensitive rules: Different policies for different environments, tenants, or load conditions

Real-World Scenarios

  1. Cost Control: A financial services agent should not execute high-cost operations (e.g., market data queries) outside trading hours (9 AM - 4 PM EST) to avoid unnecessary expenses.

  2. Quota Management: An agent approaching its daily API quota (< 100 calls remaining) should automatically throttle, backoff, or disable non-critical tools.

  3. Congestion Avoidance: During peak load periods (e.g., 2-4 PM), agents should adopt exponential backoff strategies to avoid overwhelming downstream services.

  4. Budget Exhaustion: When monthly budget is exhausted, agents should temporarily disable expensive tools (web_search, image_generation) while keeping critical operations (database queries) available.

  5. Maintenance Windows: Production deployments should be blocked during weekend maintenance windows.

Proposed Solution

Extend the Policy Engine (v1.0) with dynamic policy conditions that evaluate against runtime context in addition to action properties.

Key Features

1. Temporal Conditions

- name: restrict-expensive-ops-after-hours
  condition: |
    action.cost_estimate > 10 and
    (context.time.hour < 9 or context.time.hour >= 18)
  action: deny
  description: "High-cost operations only allowed 9 AM - 6 PM"

2. Resource-Aware Policies

- name: block-when-over-budget
  condition: context.cost.budget_remaining <= 0
  action: deny
  metadata:
    blocked_tools:
      - web_search
      - image_generation

- name: throttle-near-quota
  condition: context.quota.api_calls_remaining < 100
  action: allow
  metadata:
    backoff_strategy: exponential
    initial_delay_ms: 1000

3. Agent Behavior Adaptation

When a dynamic policy triggers, agents receive structured guidance:

result = policy_evaluator.evaluate(
    action_dict={"type": "web_search", "query": "..."},
    dynamic_context={
        "time": {"hour": 22, "day_of_week": 6},
        "cost": {"budget_remaining": 25},
        "quota": {"api_calls_remaining": 15},
    }
)

if result.metadata.get("backoff_seconds"):
    time.sleep(result.metadata["backoff_seconds"])

if result.metadata.get("blocked_tools"):
    agent.disable_tools(result.metadata["blocked_tools"])

4. Dynamic Context Model

DynamicContext = {
    "time": {
        "timestamp": int,        # Unix epoch (UTC)
        "hour": int,             # 0-23
        "day_of_week": int,      # 1=Monday, 7=Sunday
        "timezone": str,
    },
    "cost": {
        "budget_total": float,
        "budget_used": float,
        "budget_remaining": float,
    },
    "quota": {
        "api_calls_remaining": int,
        "rate_limit_remaining": int,
    },
    "system": {
        "load": float,           # 0.0-1.0
        "error_rate": float,
    },
}

Implementation Approach

  1. Extend PolicyEvaluator.evaluate() to accept optional dynamic_context parameter
  2. Inject dynamic context into condition evaluation alongside action properties
  3. Return structured metadata when policies trigger (backoff hints, tool blocks, retry-after)
  4. Provide context utilities (TimeContext.now(), CostTracker, QuotaTracker)
  5. Maintain backward compatibility - policies without context.* references work unchanged

Specification

I've drafted a detailed specification: docs/specs/DYNAMIC-POLICY-CONDITIONS-1.0.md

This covers:

  • Dynamic context schema (time, cost, quota, system, agent)
  • Temporal condition operators
  • Resource-aware policy patterns
  • Agent behavior adaptation signals
  • Evaluation semantics and backward compatibility
  • Security considerations (clock tampering, context injection attacks)

Alternatives Considered

Alternative 1: External Policy Decision Point (PDP)

Use OPA/Cedar with external data sources for time/budget checks.

Pros: Leverages existing policy engines
Cons: Adds deployment complexity, increases latency, requires separate state management

Alternative 2: Pre/Post-Execution Hooks

Let agents query budget/quota before each action via hooks.

Pros: Keeps policy engine simple
Cons: Pushes complexity to agent code, inconsistent patterns across frameworks, no centralized enforcement

Alternative 3: Policy Reloading

Dynamically reload policies based on time/budget triggers.

Pros: No schema changes
Cons: Slow (policy reload overhead), doesn't handle fine-grained conditions, no agent adaptation signals

Benefits

  1. Unified Governance: Time, cost, and quota constraints expressed in same policy language as security rules
  2. Agent Simplicity: Agents don't need separate budget/quota checking logic - policy engine handles it
  3. Auditability: Dynamic context is logged with every decision (timestamp, budget snapshot, quota state)
  4. Flexibility: Policies adapt to runtime conditions without code changes
  5. Production-Ready Patterns: Circuit breakers, backoff, tool disabling built into policy layer

Priority

Important - Needed for production deployments where cost control, quota management, and adaptive behavior are requirements.

Questions for Maintainers

  1. Does this fit the roadmap for Policy Engine 1.1 or should it be a separate package?
  2. Should dynamic context be mandatory or optional (backward compat preference)?
  3. Any concerns about the proposed schema or evaluation semantics?
  4. Interest in multi-language implementation (Python + TypeScript + .NET)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesttriageNeeds triage

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions