Cookbook
All recipes
Agent trajectory timelineAgent memory

Agent memory

Search and retrieval

Data quality

Graph analytics

Geospatial

Cookbook / Agent memory · Intermediate

Agent trajectory timeline

An agent runtime appends one step per tool call to a session's timeline. On every turn it asks for the last few steps, the page before those, and everything since a cutoff; a supervisor asks for the newest steps across all sessions. Four constraints make those newest-first reads correct by construction, and one statement migrates a timeline that was written the other way.

The graph is (:Session {id})-[:STEP {ts, seq, tokens}]->(:Step {id, kind, text, at})-[:CALLED]->(:Tool {name}). ts is the sort key: epoch milliseconds, stored as an integer. at keeps the same instant as a datetime for display. tokens sits on the relationship, so a budget read never touches the Step nodes. The catalog of problems relate solves lists this pattern as the agent trajectory timeline.

Data model: a session's steps, each calling one toolA Session links to each of its Step nodes by a STEP relationship that carries an integer timestamp, a sequence number and a token count. Each Step has a kind, text and time, and a CALLED relationship to the one Tool it used.SessionidStepid · kindtext · atToolnameSTEPts (integer) · seq · tokensCALLED
Data model: a session's steps, each calling one toolA Session links to each of its Step nodes by a STEP relationship that carries an integer timestamp, a sequence number and a token count. Each Step has a kind, text and time, and a CALLED relationship to the one Tool it used.SessionidStepid · kindtext · atToolnameSTEPts (integer) · seq · tokensCALLED
Data model: a session's steps, each calling one tool

Lock the timeline down

Four constraints. session_id makes the per-session anchor one node, and tool_name lets MERGE keep one node per tool, so a read that hops on to the tool cannot fan out. The last two say that every STEP has a ts, and that it is an integer.

Step 1
CREATE CONSTRAINT session_id IF NOT EXISTS FOR (s:Session) REQUIRE s.id IS UNIQUE;
CREATE CONSTRAINT tool_name IF NOT EXISTS FOR (t:Tool) REQUIRE t.name IS UNIQUE;
CREATE CONSTRAINT step_ts IF NOT EXISTS FOR ()-[r:STEP]-() REQUIRE r.ts IS :: INTEGER;
CREATE CONSTRAINT step_ts_nn IF NOT EXISTS FOR ()-[r:STEP]-() REQUIRE r.ts IS NOT NULL;
SHOW CONSTRAINTS YIELD name, type, entityType, labelsOrTypes, properties
RETURN name, type, entityType, labelsOrTypes, properties
ORDER BY name
Recorded result
nametypeentityTypelabelsOrTypesproperties
"session_id""NODE_PROPERTY_UNIQUENESS""NODE"["Session"]["id"]
"step_ts""RELATIONSHIP_PROPERTY_TYPE""RELATIONSHIP"["STEP"]["ts"]
"step_ts_nn""RELATIONSHIP_PROPERTY_EXISTENCE""RELATIONSHIP"["STEP"]["ts"]
"tool_name""NODE_PROPERTY_UNIQUENESS""NODE"["Tool"]["name"]

4 rows · constraints added: 4

Why an integer? Relate keeps each node's relationships of one type in ts order when ts is an integer (ADR-0035). A read with one anchor node, one typed hop, and ORDER BY t.ts DESC LIMIT n then walks the newest relationships first and stops after n, instead of sorting the whole session.

Note Only an integer ts is kept in order. Over a ts that holds a datetime or an ISO string, Relate currently answers the same read with the first steps ever written, labelled newest-first, and no error. The two ts constraints make that shape impossible to write.

The type and the presence are two constraints because a property type constraint cannot carry NOT NULL:

Step 2
CREATE CONSTRAINT step_ts_strict IF NOT EXISTS
  FOR ()-[r:STEP]-() REQUIRE r.ts IS :: INTEGER NOT NULL
Expected error
error: syntax error: INTEGER NOT NULL is not supported in property type constraints.

Load three sessions

The fixture is one steps list: 40 steps in each of three sessions, plus one more for s1. That last row is s1's step 0, backfilled after a restart: it is written last but carries the oldest timestamp, so creation order and time order disagree. datetime(r.at).epochMillis turns each ISO timestamp into the integer sort key. A step's id is its session and sequence number.

Step 3
Show the setup step
UNWIND $steps AS r
MERGE (s:Session {id: r.sid})
MERGE (tool:Tool {name: r.tool})
CREATE (s)-[:STEP {ts: datetime(r.at).epochMillis, seq: r.seq, tokens: r.tokens}]->
       (:Step {id: r.sid + ':' + toString(r.seq), kind: r.kind, text: r.text,
               at: datetime(r.at)})-[:CALLED]->(tool);

MATCH (s:Session) WITH count(s) AS sessions
MATCH (t:Tool) WITH sessions, count(t) AS tools
MATCH ()-[t:STEP]->()
RETURN sessions, tools, count(t) AS steps
Loads steps.json (20 KB)
Recorded result
sessionstoolssteps
36121

1 row · nodes created: 130, relationships created: 242, properties set: 856, labels added: 130

Six distinct tool names in the fixture, six Tool nodes.

A bad append is refused

A runtime that copies a timestamp as a datetime, instead of converting it, fails loudly instead of corrupting the order:

Step 4
MATCH (s:Session {id: 's1'}), (tool:Tool {name: 'shell'})
CREATE (s)-[:STEP {ts: datetime('2024-01-07T00:42:00Z'), seq: 41, tokens: 10}]->
       (:Step {id: 's1:41', kind: 'answer', text: 'copied a datetime',
               at: datetime('2024-01-07T00:42:00Z')})-[:CALLED]->(tool)
Expected error
error: semantic error: ConstraintValidationFailed: `step_ts` property type

A step with no ts at all fails the same way, on step_ts_nn.

The last N steps

The agent's per-turn read: one session, newest first.

Step 5
MATCH (s:Session {id: $sid})-[t:STEP]->(x:Step)
RETURN t.seq AS seq, x.kind AS kind, x.text AS text
ORDER BY t.ts DESC
LIMIT $n
Parameters
Recorded result
seqkindtext
40"answer""answer: run the epochMillis probe"
39"observation""observation: ask about epochMillis"

2 rows

The next page

"Show me more" is the same read with SKIP. It stays on the ordered walk: the walk stops after skip + n steps.

Step 6
MATCH (s:Session {id: $sid})-[t:STEP]->(x:Step)
RETURN t.seq AS seq, x.kind AS kind
ORDER BY t.ts DESC
SKIP $skip
LIMIT $n
Parameters
Recorded result
seqkind
38"tool_call"
37"plan"

2 rows

Everything since a cutoff

The caller sends an ISO timestamp. LET names the cutoff once, as epoch milliseconds, and FILTER keeps the steps after it (both are Cypher 25; a WHERE says the same). With no LIMIT, the read sorts the steps it keeps instead of walking in order, which is fine for a bounded window.

Step 7
MATCH (s:Session {id: $sid})-[t:STEP]->(x:Step)
LET cutoff = datetime($since).epochMillis
FILTER t.ts > cutoff
RETURN t.seq AS seq, x.kind AS kind
ORDER BY t.ts DESC
Parameters
Recorded result
seqkind
40"answer"
39"observation"
38"tool_call"
37"plan"

4 rows

The oldest step

Ascending order finds the backfilled step, even though it was written last. datetime.fromEpochMillis turns the integer back into a datetime inside Cypher; it equals the at stored on the step, so a runtime that keeps only ts loses nothing.

Step 8
MATCH (s:Session {id: $sid})-[t:STEP]->(x:Step)
WITH t, x ORDER BY t.ts ASC LIMIT 1
RETURN t.seq AS seq, t.ts AS ts, x.at AS at,
       datetime.fromEpochMillis(t.ts) = x.at AS matches_at, x.text AS text
Parameters
Recorded result
seqtsatmatches_attext
01704585600000"2024-01-07T00:00:00Z"true"system: load task context (backfilled after a restart)"

1 row

Note Use datetime.fromEpochMillis(ms). Relate currently returns 0000-01-01T00:00Z for datetime({epochMillis: ms}) and datetime({epochSeconds: s}) instead of the instant.

The session on a time axis

Every step of one session, oldest first, with the datetime at beside its kind. The backfilled step 0 opens the axis, although it was written last.

Step 9
MATCH (s:Session {id: $sid})-[t:STEP]->(x:Step)
RETURN t.seq AS seq, x.kind AS kind, x.at AS at
ORDER BY t.ts
Parameters
Recorded result
seqkindat
0"system""2024-01-07T00:00:00Z"
1"plan""2024-01-07T00:01:14.647Z"
2"tool_call""2024-01-07T00:02:32.928Z"
3"observation""2024-01-07T00:03:51.476Z"
4"plan""2024-01-07T00:04:48.677Z"
5"tool_call""2024-01-07T00:05:42.969Z"
6"observation""2024-01-07T00:06:30.713Z"
7"plan""2024-01-07T00:07:26.034Z"
8"tool_call""2024-01-07T00:08:45.661Z"
9"observation""2024-01-07T00:09:43.126Z"
10"plan""2024-01-07T00:10:58.53Z"
11"tool_call""2024-01-07T00:11:56.33Z"
12"observation""2024-01-07T00:13:00.607Z"
13"plan""2024-01-07T00:13:51.176Z"
14"tool_call""2024-01-07T00:15:02.834Z"
15"observation""2024-01-07T00:16:04.479Z"
16"plan""2024-01-07T00:17:08.421Z"
17"tool_call""2024-01-07T00:18:00.494Z"
18"observation""2024-01-07T00:19:10.824Z"
19"plan""2024-01-07T00:19:55.859Z"
20"tool_call""2024-01-07T00:21:11.66Z"
21"observation""2024-01-07T00:22:24.171Z"
22"plan""2024-01-07T00:23:22.179Z"
23"tool_call""2024-01-07T00:24:12.89Z"
24"observation""2024-01-07T00:25:24.763Z"
25"plan""2024-01-07T00:26:16.385Z"
26"tool_call""2024-01-07T00:27:33.289Z"
27"observation""2024-01-07T00:28:30.635Z"
28"plan""2024-01-07T00:29:24.218Z"
29"tool_call""2024-01-07T00:30:16.853Z"
30"observation""2024-01-07T00:31:01.883Z"
31"plan""2024-01-07T00:31:48.169Z"
32"tool_call""2024-01-07T00:32:39.744Z"
33"observation""2024-01-07T00:33:53.68Z"
34"plan""2024-01-07T00:35:00.238Z"
35"tool_call""2024-01-07T00:35:50.106Z"
36"observation""2024-01-07T00:36:51.032Z"
37"plan""2024-01-07T00:38:00.391Z"
38"tool_call""2024-01-07T00:39:17.092Z"
39"observation""2024-01-07T00:40:14.073Z"
40"answer""2024-01-07T00:41:14.04Z"

41 rows

The timeline draws those rows, one lane per kind. Its slider sets the since cutoff from Everything since a cutoff and runs that step again for the same session, so the steps it keeps light up.

The session step's recorded rows on a time axis: 41 rows in 5 lanes by kind, from 2024-01-07T00:00:00Z to 2024-01-07T00:41:14.04Z.

kind rows seq earliest at latest at
system 1 0 2024-01-07T00:00:00Z 2024-01-07T00:00:00Z
plan 13 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37 2024-01-07T00:01:14.647Z 2024-01-07T00:38:00.391Z
tool_call 13 2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38 2024-01-07T00:02:32.928Z 2024-01-07T00:39:17.092Z
observation 13 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39 2024-01-07T00:03:51.476Z 2024-01-07T00:40:14.073Z
answer 1 40 2024-01-07T00:41:14.04Z 2024-01-07T00:41:14.04Z
The session step's rows on a time axis, as recorded41 rows of the session step on a time axis from 2024-01-07T00:00:00Z to 2024-01-07T00:41:14.04Z, in 5 lanes by kind: system 1, plan 13, tool_call 13, observation 13, answer 1.systemsystemplanplantool_calltool_callobservationobservationansweranswer00:002024-01-0700:1000:2000:3000:40UTCsystem, seq 0: at 2024-01-07T00:00:00Zplan, seq 1: at 2024-01-07T00:01:14.647Ztool_call, seq 2: at 2024-01-07T00:02:32.928Zobservation, seq 3: at 2024-01-07T00:03:51.476Zplan, seq 4: at 2024-01-07T00:04:48.677Ztool_call, seq 5: at 2024-01-07T00:05:42.969Zobservation, seq 6: at 2024-01-07T00:06:30.713Zplan, seq 7: at 2024-01-07T00:07:26.034Ztool_call, seq 8: at 2024-01-07T00:08:45.661Zobservation, seq 9: at 2024-01-07T00:09:43.126Zplan, seq 10: at 2024-01-07T00:10:58.53Ztool_call, seq 11: at 2024-01-07T00:11:56.33Zobservation, seq 12: at 2024-01-07T00:13:00.607Zplan, seq 13: at 2024-01-07T00:13:51.176Ztool_call, seq 14: at 2024-01-07T00:15:02.834Zobservation, seq 15: at 2024-01-07T00:16:04.479Zplan, seq 16: at 2024-01-07T00:17:08.421Ztool_call, seq 17: at 2024-01-07T00:18:00.494Zobservation, seq 18: at 2024-01-07T00:19:10.824Zplan, seq 19: at 2024-01-07T00:19:55.859Ztool_call, seq 20: at 2024-01-07T00:21:11.66Zobservation, seq 21: at 2024-01-07T00:22:24.171Zplan, seq 22: at 2024-01-07T00:23:22.179Ztool_call, seq 23: at 2024-01-07T00:24:12.89Zobservation, seq 24: at 2024-01-07T00:25:24.763Zplan, seq 25: at 2024-01-07T00:26:16.385Ztool_call, seq 26: at 2024-01-07T00:27:33.289Zobservation, seq 27: at 2024-01-07T00:28:30.635Zplan, seq 28: at 2024-01-07T00:29:24.218Ztool_call, seq 29: at 2024-01-07T00:30:16.853Zobservation, seq 30: at 2024-01-07T00:31:01.883Zplan, seq 31: at 2024-01-07T00:31:48.169Ztool_call, seq 32: at 2024-01-07T00:32:39.744Zobservation, seq 33: at 2024-01-07T00:33:53.68Zplan, seq 34: at 2024-01-07T00:35:00.238Ztool_call, seq 35: at 2024-01-07T00:35:50.106Zobservation, seq 36: at 2024-01-07T00:36:51.032Zplan, seq 37: at 2024-01-07T00:38:00.391Ztool_call, seq 38: at 2024-01-07T00:39:17.092Zobservation, seq 39: at 2024-01-07T00:40:14.073Zanswer, seq 40: at 2024-01-07T00:41:14.04Z
The session step's rows on a time axis, as recorded41 rows of the session step on a time axis from 2024-01-07T00:00:00Z to 2024-01-07T00:41:14.04Z, in 5 lanes by kind: system 1, plan 13, tool_call 13, observation 13, answer 1.systemsystemplanplantool_calltool_callobservationobservationansweranswer00:002024-01-0700:1000:2000:3000:40UTCsystem, seq 0: at 2024-01-07T00:00:00Zplan, seq 1: at 2024-01-07T00:01:14.647Ztool_call, seq 2: at 2024-01-07T00:02:32.928Zobservation, seq 3: at 2024-01-07T00:03:51.476Zplan, seq 4: at 2024-01-07T00:04:48.677Ztool_call, seq 5: at 2024-01-07T00:05:42.969Zobservation, seq 6: at 2024-01-07T00:06:30.713Zplan, seq 7: at 2024-01-07T00:07:26.034Ztool_call, seq 8: at 2024-01-07T00:08:45.661Zobservation, seq 9: at 2024-01-07T00:09:43.126Zplan, seq 10: at 2024-01-07T00:10:58.53Ztool_call, seq 11: at 2024-01-07T00:11:56.33Zobservation, seq 12: at 2024-01-07T00:13:00.607Zplan, seq 13: at 2024-01-07T00:13:51.176Ztool_call, seq 14: at 2024-01-07T00:15:02.834Zobservation, seq 15: at 2024-01-07T00:16:04.479Zplan, seq 16: at 2024-01-07T00:17:08.421Ztool_call, seq 17: at 2024-01-07T00:18:00.494Zobservation, seq 18: at 2024-01-07T00:19:10.824Zplan, seq 19: at 2024-01-07T00:19:55.859Ztool_call, seq 20: at 2024-01-07T00:21:11.66Zobservation, seq 21: at 2024-01-07T00:22:24.171Zplan, seq 22: at 2024-01-07T00:23:22.179Ztool_call, seq 23: at 2024-01-07T00:24:12.89Zobservation, seq 24: at 2024-01-07T00:25:24.763Zplan, seq 25: at 2024-01-07T00:26:16.385Ztool_call, seq 26: at 2024-01-07T00:27:33.289Zobservation, seq 27: at 2024-01-07T00:28:30.635Zplan, seq 28: at 2024-01-07T00:29:24.218Ztool_call, seq 29: at 2024-01-07T00:30:16.853Zobservation, seq 30: at 2024-01-07T00:31:01.883Zplan, seq 31: at 2024-01-07T00:31:48.169Ztool_call, seq 32: at 2024-01-07T00:32:39.744Zobservation, seq 33: at 2024-01-07T00:33:53.68Zplan, seq 34: at 2024-01-07T00:35:00.238Ztool_call, seq 35: at 2024-01-07T00:35:50.106Zobservation, seq 36: at 2024-01-07T00:36:51.032Zplan, seq 37: at 2024-01-07T00:38:00.391Ztool_call, seq 38: at 2024-01-07T00:39:17.092Zobservation, seq 39: at 2024-01-07T00:40:14.073Zanswer, seq 40: at 2024-01-07T00:41:14.04Z
The session step's rows on a time axis, as recorded

Live: the drawing reads its rows again from each run of the statement it draws on the page's database in your browser, so an edit to the statement or its parameters redraws it; Tab reaches the marks and the arrow keys move along a lane and between lanes, each mark read out with its values; where the page names an as-of statement, a time slider runs that statement again with the time as its parameter and lights up the rows it returns.

Which tool each step called

One more hop reaches the tool. Tool names are unique, so each step reaches exactly one Tool and the read returns exactly $n rows.

Step 10
MATCH (s:Session {id: $sid})-[t:STEP]->(x:Step)-[:CALLED]->(tool:Tool)
RETURN t.seq AS seq, x.kind AS kind, tool.name AS tool
ORDER BY t.ts DESC
LIMIT $n
Parameters
Recorded result
seqkindtool
40"answer""shell"
39"observation""ask_user"
38"tool_call""shell"

3 rows

To see the shape, return the paths. Open the graph view:

Step 11
MATCH p = (s:Session {id: $sid})-[t:STEP]->(x:Step)-[:CALLED]->(tool:Tool)
WITH p, t ORDER BY t.ts DESC LIMIT $n
RETURN p
Parameters
Recorded result
// 3 rows
(n0:Session {id: "s1"})-[r78:STEP {seq: 40, tokens: 782, ts: 1704588074040}]->(n48:Step {at: "2024-01-07T00:41:14.04Z", id: "s1:40", kind: "answer", text: "answer: run the epochMillis probe"})-[r79:CALLED]->(n3:Tool {name: "shell"})
(n0)-[r76:STEP {seq: 39, tokens: 358, ts: 1704588014073}]->(n47:Step {at: "2024-01-07T00:40:14.073Z", id: "s1:39", kind: "observation", text: "observation: ask about epochMillis"})-[r77:CALLED]->(n8:Tool {name: "ask_user"})
(n0)-[r74:STEP {seq: 38, tokens: 435, ts: 1704587957092}]->(n46:Step {at: "2024-01-07T00:39:17.092Z", id: "s1:38", kind: "tool_call", text: "tool_call: run the epochMillis probe"})-[r75:CALLED]->(n3)

Token budget per session

count and sum over each session's STEP relationships. The tokens are on the relationship, so the read never loads a Step node.

Step 12
MATCH (s:Session)-[t:STEP]->()
RETURN s.id AS session, count(t) AS steps, sum(t.tokens) AS tokens
ORDER BY session
Recorded result
sessionstepstokens
"s1"4118485
"s2"4018201
"s3"4019583

3 rows

The newest steps across all sessions

A supervisor wants the newest steps overall. The anchor now matches every session. Session s3 ran last, so it owns the newest three.

Step 13
MATCH (s:Session)-[t:STEP]->(x:Step)
RETURN s.id AS session, t.seq AS seq, x.kind AS kind
ORDER BY t.ts DESC, t.seq ASC
LIMIT $n
Parameters
Recorded result
sessionseqkind
"s3"40"answer"
"s3"39"observation"
"s3"38"tool_call"

3 rows

Note Keep the second sort key (t.seq ASC) when the anchor matches more than one node. It also breaks ties between equal timestamps. Without it, Relate currently returns the newest steps of the first session it walks (here s1) instead of the newest overall.

Append a step

A runtime appends the way the fixture was loaded: find the session, MERGE the tool, create the step. A live runtime passes datetime().epochMillis for now; this step uses a fixed timestamp so its result does not change. The same step then reads the last three, and the new step comes first.

Step 14
MATCH (s:Session {id: $sid})
MERGE (tool:Tool {name: $tool})
CREATE (s)-[:STEP {ts: datetime($at).epochMillis, seq: $seq, tokens: $tokens}]->
       (:Step {id: $sid + ':' + toString($seq), kind: $kind, text: $text,
               at: datetime($at)})-[:CALLED]->(tool);

MATCH (s:Session {id: $sid})-[t:STEP]->(x:Step)
RETURN t.seq AS seq, x.kind AS kind, x.text AS text
ORDER BY t.ts DESC
LIMIT $n
Parameters
Recorded result
seqkindtext
41"answer""answer: the latest-N read is correct"
40"answer""answer: run the epochMillis probe"
39"observation""observation: ask about epochMillis"

3 rows · nodes created: 1, relationships created: 2, properties set: 7, labels added: 1

Migrate a timeline written with datetimes

A timeline written before these constraints existed often has ts as a datetime. To stand in for one, this step drops the two ts constraints and writes session s2 again as session legacy, with ts: datetime(r.at):

Step 15
DROP CONSTRAINT step_ts;
DROP CONSTRAINT step_ts_nn;

UNWIND $steps AS r
WITH r WHERE r.sid = 's2'
MERGE (s:Session {id: 'legacy'})
MERGE (tool:Tool {name: r.tool})
CREATE (s)-[:STEP {ts: datetime(r.at), seq: r.seq, tokens: r.tokens}]->
       (:Step {id: 'legacy:' + toString(r.seq), kind: r.kind, text: r.text,
               at: datetime(r.at)})-[:CALLED]->(tool);

MATCH ()-[t:STEP]->()
RETURN valueType(t.ts) AS ts_type, count(t) AS steps
ORDER BY ts_type
Loads steps.json (20 KB)
Recorded result
ts_typesteps
"INTEGER NOT NULL"122
"ZONED DATETIME NOT NULL"40

2 rows · nodes created: 41, relationships created: 80, properties set: 281, labels added: 41, constraints removed: 2

Order matters. step_ts checks the relationships that already exist, so it cannot come back before the data is fixed:

Step 16
CREATE CONSTRAINT step_ts IF NOT EXISTS FOR ()-[r:STEP]-() REQUIRE r.ts IS :: INTEGER
Expected error
error: semantic error: ConstraintValidationFailed: `step_ts` property type

The migration rewrites every datetime ts as epoch milliseconds. Only datetimes match the WHERE, so a second run migrates nothing. Each SET also moves the relationship to its place in the ts order.

Step 17
MATCH ()-[t:STEP]->()
WHERE valueType(t.ts) STARTS WITH 'ZONED DATETIME'
SET t.ts = t.ts.epochMillis
RETURN count(t) AS migrated
Recorded result
migrated
40

1 row · properties set: 40

Then lock it in again, and the latest-N read on the migrated session is correct:

Step 18
CREATE CONSTRAINT step_ts IF NOT EXISTS FOR ()-[r:STEP]-() REQUIRE r.ts IS :: INTEGER;
CREATE CONSTRAINT step_ts_nn IF NOT EXISTS FOR ()-[r:STEP]-() REQUIRE r.ts IS NOT NULL;

MATCH (s:Session {id: 'legacy'})-[t:STEP]->(x:Step)
RETURN t.seq AS seq, x.kind AS kind
ORDER BY t.ts DESC
LIMIT 3
Recorded result
seqkind
40"answer"
39"observation"
38"tool_call"

3 rows · constraints added: 2

The companion example runs the same reads from the relate CLI against a file, one process per read, and times the ordered walk against a full sort.

About the data

Dataset
121 steps an agent logged in three sessions, each with a kind, the tool it called, a line of text, a timestamp, and a token count (20 KB)
Source
Synthetic, generated with a fixed seed by the examples project's 11-trajectory-timeline/generate.py
License
Apache-2.0

Every data block is published beside this page as data/<name>.json, and the whole recipe as markdown.

More in Agent memory