Pass context
Give the agent current page state and user information verified by your backend.
Give the agent the current lesson, selected order, or user preferences so it can answer in context. Use readables for page state and host context for information verified by your backend.
Prepare the integration
Start with a working Kit page, a service agent, and an embed policy. Serve the HTML below from your website. The same-origin POST /api/praxis-token route is your backend route, implemented as described in Embed tokens and users. It checks the login session and returns { token }; it is not a public Praxis endpoint. This example uses the Develop Kit and API. Your page origin must be allowed.
Send current page state
Save this HTML as a page on your website. Changing the selection updates the registered value; Kit takes a snapshot when the user sends a message.
<!doctype html>
<html lang="en">
<meta charset="utf-8" />
<title>Lesson assistant</title>
<label>Current lesson
<select id="lesson">
<option value="Lesson 3: Delivery rules">Lesson 3: Delivery rules</option>
<option value="Lesson 4: Returns">Lesson 4: Returns</option>
</select>
</label>
<button id="clear">Stop sharing the lesson</button>
<praxis-agent style="display:block;height:600px"></praxis-agent>
<script type="module">
import "https://kit-develop.praxisusercontent.com/v1/praxis-kit.js";
await customElements.whenDefined("praxis-agent");
const chat = document.querySelector("praxis-agent");
const lesson = document.querySelector("#lesson");
const update = () => chat.setReadable("lesson", { title: lesson.value });
update();
lesson.addEventListener("change", update);
document.querySelector("#clear").addEventListener("click", () => {
chat.removeReadable("lesson");
});
chat.addEventListener("praxis.log", event => console.warn(event.detail));
chat.setOptions({
api: {
url: "https://api-develop.deepraxis.com",
getToken: async () => {
const response = await fetch("/api/praxis-token", {
method: "POST", credentials: "same-origin",
});
if (!response.ok) throw new Error(`Token request failed: ${response.status}`);
const { token } = await response.json();
if (typeof token !== "string" || !token) throw new Error("Missing token");
return token;
},
},
agent: { name: "Lesson assistant" },
});
</script>
</html>Expected result: ask which lesson is open. The agent receives lesson 3. Select lesson 4 and send another message: that message carries the new value. After clicking Stop sharing the lesson, later messages omit the item.
setReadable(name, value) accepts a string or JSON-serializable value. Names must match [A-Za-z0-9_.:-]{1,64}. Setting the same name replaces its value; removeReadable(name) removes it. Invalid names and non-serializable values throw without replacing the previous registration.
Each message can carry at most 32 items and 4096 UTF-8 bytes for the entire context JSON. Kit drops the earliest registered items from that snapshot until it fits. A praxis.log event has level warn, with dropped names in data.names. Registrations remain available; smaller values can be sent again.
Page context is attached to the current user message and marked untrusted. Each message gets a fresh snapshot, but removing a registration does not erase information in earlier messages. Page state cannot establish identity, account balances, or order ownership.
Send backend-verified information
Include system_message when your backend issues a token. Run this request on the server. Replace the public agent ID and derive the user ID from your authenticated login session. Never put PRAXIS_API_KEY or this command in a browser page.
curl --fail-with-body https://api-develop.deepraxis.com/agent/v1/embed_tokens \
-X POST \
-H "Authorization: Bearer $PRAXIS_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"agent": "agent_example",
"external_user_id": "customer_123",
"system_message": [{"type": "text", "text": "The customer prefers English replies."}]
}'Expected result: HTTP 201 with token, id, and expires_at. Return only the required short-lived credentials through your host route. Create a new session with that token to include the preference in model context. Keep tokens out of shared logs.
system_message is an array of { type: "text", text } blocks, limited to 8192 UTF-8 bytes of text. Use one block to avoid additional separators increasing the size. This information is visible to the model; it is not secret storage.
For an existing session, an API Key holder can append system.message through Send events. Replacing a token does not rewrite the context of an established session.
Choose another input
| Information | Where to provide it |
|---|---|
| Shared role and tone | Dashboard: 配置 → 指令 (Configuration → Instructions) |
| Replacement instructions for one token | agent_override.system during issuance; first enable 允许宿主覆盖指令 under 配置 → 安全. null clears instructions |
| Page data needed only on demand | Client tools |
| Protected or frequently changing order data | Server tools that scope access to the end user |
An override without policy permission returns HTTP 400 with EMBED_FIELD_NOT_ALLOWED. Change the policy or remove the field before issuing another token. Repeating the unchanged request cannot resolve it.
Verify the context
In browser Network tools, send a message and inspect praxis_context.items. It should contain name: "lesson" and the current lesson as a string value. Change the lesson, then remove it, sending a message after each action. Check the requests rather than relying only on the model's answer.
For host context, create a new session with the newly issued token. Ask about the preferred reply language and compare it with your issuance request. This checks the experience; identity and authorization still belong to your backend and tools.
Next: Client tools · Secure your integration · Agent API.