> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentscope.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> For AgentScope Python, use https://docs.agentscope.io/stable/en/index for new projects. For existing projects, check the installed agentscope version and use matching versioned documentation.
> The /latest/ alias points to development documentation. Use it only with the matching development source. Do not mix AgentScope 1.x and 2.x APIs.
> State the AgentScope version when providing installation commands or code examples. ReMe uses its own continuously updated /reme/latest/ documentation.

# Environment Awareness

> Keep the agent aware of time, tasks, and context usage as they change

An agent stays aware of its changing environment through **runtime state injection**: before each reasoning step, information that changes across turns (current time, plan tasks, context usage) is injected into the context as a `HintBlock`, configured via the `injection_config` parameter of `Agent(...)`.

The injection covers three dimensions, each with its own timing rule:

| Dimension | Injected Content | When It Is Injected |
| - | - | - |
| Time | The current wall-clock time and its timezone | No time is recorded in the context (the first reply, or right after a context compression), or the elapsed time since the recorded one exceeds `time_interval` hours |
| Plan tasks | The counts of in-progress and pending tasks, with a reminder to call `TaskList` | Uncompleted tasks exist while the context contains neither task-related tool calls (e.g. compressed away) nor a previous tasks injection |
| Context usage | The current input tokens and the compression threshold | At the first iteration of a reply, when the input tokens come within `context_buffer_ratio` of the compression threshold, letting the agent perceive that a compression is near |

## How Injection Works

Each injected field is wrapped as `<key>value</key>`, and all fields are joined and placed into the `template` (a `<system-reminder>` wrapper by default). A typical injected hint looks like:

```text Example Injected Hint theme={null}
<system-reminder>Treat the following as the ground truth at this point of the conversation. Anything stated earlier is outdated, and a later reminder, if any, supersedes this one:
<current-time>2026-07-22T10:30:00</current-time>
<timezone>Asia/Shanghai</timezone>
<tasks>You have 1 in-progress tasks and 2 pending tasks. Use `TaskList` to view them if you don't know.</tasks>
</system-reminder>
```

Three design decisions are worth knowing:

* The injection is **not ephemeral**: it is appended to the persistent context on purpose, so the agent can perceive how time elapses and what it did at each step, building a sense of time.
* The hint is attached as a `HintBlock` instead of mutating the system prompt, so prompt caching still works while the agent stays aware of the changing state.
* Only information that **changes** within a conversation is injected. Fixed information (the agent's identity, standing instructions) belongs in the system prompt.

When an injection happens and `emit_hint_event` is enabled, `reply_stream` also yields a `HintBlockEvent`, so a frontend can render the injected hint.

## Configure Injection

Pass an `InjectionConfig` to the agent constructor to tune the injection behavior:

```python theme={null}
from agentscope.agent import Agent, InjectionConfig
from agentscope.model import DashScopeChatModel
from agentscope.credential import DashScopeCredential

agent = Agent(
    name="my_agent",
    system_prompt="You are a helpful assistant.",
    model=DashScopeChatModel(
        credential=DashScopeCredential(api_key="YOUR_API_KEY"),
        model="qwen-max",
    ),
    injection_config=InjectionConfig(
        timezone="Asia/Shanghai",  # inject the time of this timezone
        time_interval=1.0,         # refresh the time at most once per hour
    ),
)
```

The fields of `InjectionConfig`:

| Field | Default | Description |
| - | - | - |
| `inject_runtime_state` | `True` | Master switch; set `False` to disable runtime state injection entirely |
| `timezone` | `"UTC"` | Timezone of the injected time, in the standard timezone database format (e.g. `"Asia/Shanghai"`) |
| `time_format` | `"%Y-%m-%dT%H:%M:%S"` | Format of the injected time; must carry the date part so the recorded time round-trips as a full timestamp |
| `time_interval` | `0.5` | Minimum elapsed time in hours from the recorded time to trigger a new time injection |
| `context_buffer_ratio` | `0.2` | Buffer ahead of the compression threshold; with a trigger ratio of 0.8 and a buffer of 0.2, context usage is injected once the input tokens exceed 60% of the model context size |
| `template` | A `<system-reminder>` wrapper | Template around the injected fields; must contain the `{runtime_state}` placeholder |
| `injection_source` | `{"label": "System", "sublabel": "Runtime State"}` | The `source` of the injected `HintBlock`, used to recognize the agent's own previous injections when scanning the context |
| `task_tool_names` | `TaskCreate`, `TaskGet`, `TaskList`, `TaskUpdate` | Tool names whose calls in the context indicate the agent is already aware of the tasks, suppressing the tasks injection |
| `extra_fields` | `{}` | Custom fields attached to every injection (see [Inject Custom Fields](#inject-custom-fields)) |
| `emit_hint_event` | `True` | Whether to emit a `HintBlockEvent` when an injection happens |

<Note>
  `context_buffer_ratio` must be smaller than the `trigger_ratio` of the [context config](/en/versions/2.0.6/building-blocks/context/compress-context#configure-compression), so that the context usage is injected before the compression happens. Otherwise the agent constructor raises a `ValueError`.
</Note>

## Inject Custom Fields

Beyond the built-in dimensions, `extra_fields` injects developer-defined information, such as sensor readings or deployment metadata:

```python theme={null}
from agentscope.agent import InjectionConfig

injection_config = InjectionConfig(
    extra_fields={
        "battery-level": "78%",       # injected as <battery-level>78%</battery-level>
        "location": "Hangzhou office",
    },
)
```

Extra fields are attached to **every** injection but never trigger one by themselves: they ride along whenever the time, tasks, or context dimension fires.

## Customize the Template

The `template` field controls how the injected fields are presented to the LLM. It must contain the `{runtime_state}` placeholder, which is replaced by the joined `<key>value</key>` fields:

```python theme={null}
from agentscope.agent import InjectionConfig

injection_config = InjectionConfig(
    template=(
        "[Runtime update] The following reflects the current environment:\n"
        "{runtime_state}"
    ),
)
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.