@borgee/agents-host 0.2.35 → 0.2.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents-host.d.ts +2 -0
- package/dist/agents-host.js +111 -44
- package/dist/chat/sdk-chat-control-plane.js +3 -0
- package/dist/context/injection.d.ts +5 -3
- package/dist/context/injection.js +45 -29
- package/dist/context/prompt.js +23 -35
- package/dist/context/skill-manual.d.ts +13 -0
- package/dist/context/skill-manual.js +18 -0
- package/dist/context/turn-preparation.js +13 -4
- package/dist/gateway/localhost-gateway.js +16 -8
- package/dist/hosted-turn-content.d.ts +15 -0
- package/dist/hosted-turn-content.js +50 -0
- package/dist/managed-daemon.d.ts +3 -2
- package/dist/managed-daemon.js +77 -29
- package/dist/providers/claude/adapter.d.ts +3 -1
- package/dist/providers/claude/adapter.js +10 -0
- package/dist/providers/claude/cli-client.d.ts +11 -2
- package/dist/providers/claude/cli-client.js +98 -27
- package/dist/providers/codex/adapter.d.ts +3 -1
- package/dist/providers/codex/adapter.js +10 -0
- package/dist/providers/codex/cli-client.d.ts +10 -2
- package/dist/providers/codex/cli-client.js +85 -21
- package/dist/providers/codex/project-doc.js +13 -29
- package/dist/providers/copilot/adapter.d.ts +3 -1
- package/dist/providers/copilot/adapter.js +10 -0
- package/dist/providers/copilot/cli-client.d.ts +9 -1
- package/dist/providers/copilot/cli-client.js +71 -8
- package/dist/providers/create-provider.d.ts +1 -1
- package/dist/providers/create-provider.js +16 -5
- package/dist/providers/provider-adapter.d.ts +35 -0
- package/dist/providers/provider-adapter.js +44 -1
- package/dist/state-paths.d.ts +9 -1
- package/dist/state-paths.js +22 -3
- package/dist/types.d.ts +33 -2
- package/package.json +1 -1
- package/skills/borgee-agent/SKILL.md +119 -38
- package/skills/borgee-agent/references/errors.md +38 -0
- package/skills/borgee-agent/references/task-properties.md +30 -0
- package/skills/borgee-agent/scripts/borgee-agent.mjs +553 -0
- package/skills/borgee-agent/scripts/borgee-agent.py +547 -0
- package/skills/borgee-agent/borgee-agent.mjs +0 -562
- package/skills/borgee-agent/borgee-agent.py +0 -469
|
@@ -1,52 +1,133 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
name: borgee-agent
|
|
3
|
+
description: Read the Borgee channel this turn is running in and act on its tasks — channel history, visible participants, task list/create/get/update, task properties, and short auxiliary mentions — through the packaged local CLI. Use when you need to know what was said in this channel, who is here, or what the current task is, and when you need to record task state or ping another participant.
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# Borgee channel agent
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
This turn is running as an agent inside a Borgee channel. The packaged CLI is the only way to see that channel and to act on its tasks: it talks to a loopback-only gateway that is already authorized for this channel and this turn. This file is the whole manual — the invocation, every command, what is reachable when, and the limits.
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
- Python: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --print-bootstrap`
|
|
9
|
-
- Node health: `node ./borgee-agent.mjs --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --health`
|
|
10
|
-
- Node bootstrap: `node ./borgee-agent.mjs --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --read-bootstrap`
|
|
11
|
-
- Node identity: `node ./borgee-agent.mjs --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --get-me`
|
|
12
|
-
- Node history: `node ./borgee-agent.mjs --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --read-history --limit 20`
|
|
13
|
-
- Node private draft snapshot: `node ./borgee-agent.mjs --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --turn-execution-id turn-id --read-draft`
|
|
14
|
-
- Node users: `node ./borgee-agent.mjs --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --list-users`
|
|
15
|
-
- Node auxiliary mention: `node ./borgee-agent.mjs --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --turn-execution-id turn-id --send-mention user-id --body "Need review from <@user-id>"`
|
|
16
|
-
- Node auxiliary reply: `node ./borgee-agent.mjs --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --turn-execution-id turn-id --send-message --body "Following up here" --reply-to message-id`
|
|
17
|
-
- Python health: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --health`
|
|
18
|
-
- Python bootstrap: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --read-bootstrap`
|
|
19
|
-
- Python identity: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --get-me`
|
|
20
|
-
- Python history: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --read-history --limit 20`
|
|
21
|
-
- Python private draft snapshot: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --turn-execution-id turn-id --read-draft`
|
|
22
|
-
- Python users: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --list-users`
|
|
23
|
-
- Python auxiliary mention: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --turn-execution-id turn-id --send-mention user-id --body "Need review from <@user-id>"`
|
|
24
|
-
- Python auxiliary reply: `python3 ./borgee-agent.py --context /absolute/path/to/context.json --auth-path /absolute/path/to/.localhost-gateway-auth.json --turn-execution-id turn-id --send-message --body "Following up here" --reply-to message-id`
|
|
10
|
+
## Authorization
|
|
25
11
|
|
|
26
|
-
|
|
12
|
+
Every command below is already authorized on a turn whose prompt names a gateway credential file. Run it directly. Never ask the user for permission first, and never end a turn having asked to read instead of reading.
|
|
27
13
|
|
|
28
|
-
|
|
29
|
-
- Task-assignment thread (`taskAssignmentContext.active: true`): `--get-task`, `--update-task`, `--set-property` and `--delete-property` may omit `--task-id` and resolve the current thread task through the persisted `currentTaskId` or an agents-host local fallback; `--read-task-history --task-id ...` still works for that thread's own task, while `--create-task` and `--list-tasks` stay disabled and must be run from the parent channel
|
|
14
|
+
## When to use it
|
|
30
15
|
|
|
31
|
-
|
|
16
|
+
- You are asked what was said here, who is here, or what you are supposed to be working on: read it, do not guess.
|
|
17
|
+
- You have made progress worth recording on the task: a status change, or a property such as the pull request that implements it.
|
|
32
18
|
|
|
33
|
-
##
|
|
19
|
+
## When not to use it
|
|
34
20
|
|
|
35
|
-
|
|
21
|
+
- For your final answer. The host posts your turn's reply itself; sending it again through this CLI double-posts it.
|
|
22
|
+
- To find the gateway credential file. The absolute path is in this turn's prompt; the CLI never searches for it, and a file found by searching is not trusted.
|
|
36
23
|
|
|
37
|
-
|
|
38
|
-
- Delete: `node ./borgee-agent.mjs --context ... --auth-path ... --delete-property "link.pr"`
|
|
24
|
+
## Invocation
|
|
39
25
|
|
|
40
|
-
|
|
26
|
+
`scripts/borgee-agent.mjs` and `scripts/borgee-agent.py`, both in the `scripts/` directory beside this file, are the same tool: they accept the same grammar and print the same bytes. Neither is marked executable, so name the interpreter your host has and give the script its absolute path — this file's own directory plus `scripts/`:
|
|
41
27
|
|
|
42
|
-
|
|
28
|
+
```
|
|
29
|
+
node <this file's directory>/scripts/borgee-agent.mjs --gateway <absolute path> <command> [arguments]
|
|
30
|
+
python3 <this file's directory>/scripts/borgee-agent.py --gateway <absolute path> <command> [arguments]
|
|
31
|
+
```
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
- `link.issue` — the issue or ticket the task originates from.
|
|
46
|
-
- `agent.session_id` — **do not write this**. agents-host records the provider session itself after each turn.
|
|
33
|
+
Everything below writes that leading interpreter and script path as `borgee-agent`.
|
|
47
34
|
|
|
48
|
-
|
|
35
|
+
`--gateway` takes the absolute path this turn's prompt gives you. That one file is the whole handoff: which channel you are in, where the gateway listens, and the token that authorizes you. The token is rotated every turn, so read the path out of the current prompt rather than reusing one you remember.
|
|
49
36
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
## Commands
|
|
38
|
+
|
|
39
|
+
| Command | What you get |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `health` | Reachability. The only command that answers without the token, so it tells a dead gateway from a rotated one. |
|
|
42
|
+
| `bootstrap` | The channel context the host published for this turn: the channel id, whether collaboration is live, and inside a task thread the current task id. The one command whose answer you cannot predict. |
|
|
43
|
+
| `whoami` | This agent's own id and display name. |
|
|
44
|
+
| `history [--limit <n>] [--before <n>] [--after <n>]` | Recent messages in this channel. At most 20 per call — a larger `--limit` is silently reduced to 20, so page with `--before` rather than asking for more. `--before` and `--after` are `createdAt` epoch-millisecond cursors copied from a message you already hold, not message ids and not counts. |
|
|
45
|
+
| `users` | Every participant you share a channel, DM or thread with. That is a superset of this channel's members, not its roster. |
|
|
46
|
+
| `draft --turn-execution-id <id>` | This turn's host-private in-flight draft. It exists only once this turn has produced visible reply text, and answers `not_found` before that. |
|
|
47
|
+
| `send --body <text> --turn-execution-id <id> (--reply-to <message-id> \| --mention <user-id>)...` | Post a short auxiliary message. It must address someone. |
|
|
48
|
+
| `mention <user-id> --body <text> --turn-execution-id <id> [--reply-to <message-id>]` | Post a short auxiliary message addressed to one participant. |
|
|
49
|
+
| `task list` | Tasks in this channel. Parent channel only. |
|
|
50
|
+
| `task create --title <text> [--description <text>] [--assignee-id <user-id>]` | Create a task. Parent channel only. |
|
|
51
|
+
| `task get [<task-id>]` | One task with its properties. |
|
|
52
|
+
| `task update [<task-id>] [--status <open\|in_progress\|in_review\|done\|cancelled>] [--title <text>] [--description <text>] [--assignee-id <user-id>]` | Update the task. At least one field is required. |
|
|
53
|
+
| `task history <task-id> [--limit <n>] [--before <n>] [--after <n>]` | Messages in that task's thread. Same 20-per-call cap and the same `createdAt` cursors as `history`. |
|
|
54
|
+
| `task set-property [<task-id>] --key <key> --value <value>` | Set one task property. |
|
|
55
|
+
| `task delete-property [<task-id>] --key <key>` | Remove one task property. |
|
|
56
|
+
|
|
57
|
+
On `task get`, `task update`, `task set-property` and `task delete-property` the task id is an optional leading positional. Inside a task thread, omitting it addresses this thread's own task: the host's published binding names it, and where the host published none the gateway scans the parent channel's visible tasks for this thread instead — so pass the id explicitly when that scan cannot land on a single task. `task list` and `task create` are refused inside a task thread; they belong to the parent channel. In a parent channel every one of those ids is required, and omitting it answers `not_found`.
|
|
58
|
+
|
|
59
|
+
The keys `task set-property` and `task delete-property` accept are a closed set, and a value has a size limit: see `references/task-properties.md`.
|
|
60
|
+
|
|
61
|
+
## What is available on a turn
|
|
62
|
+
|
|
63
|
+
`health`, `bootstrap`, `whoami`, `history` and the task commands are live on every turn whose prompt names a gateway credential file.
|
|
64
|
+
|
|
65
|
+
`users`, `draft`, `send` and `mention` are live only where collaboration is enabled; the prompt says when it is not, and the gateway answers `not_found` for all four. `draft`, `send` and `mention` additionally need the turn execution id the prompt carries: no command returns that id and the gateway credential file does not hold it.
|
|
66
|
+
|
|
67
|
+
A `not_found` from `draft` therefore has two readings — collaboration is off, or the host holds no draft for this turn yet — so take it as an answer about the draft, not as evidence that `users`, `send` and `mention` have gone.
|
|
68
|
+
|
|
69
|
+
Whether you are in a parent channel or inside a task assignment thread is in the prompt too, and it decides which task grammar above applies.
|
|
70
|
+
|
|
71
|
+
## Inside a task thread
|
|
72
|
+
|
|
73
|
+
The assigned work belongs to that thread, and your ordinary final reply is the completion report.
|
|
74
|
+
|
|
75
|
+
- `task update --status in_progress` when you start.
|
|
76
|
+
- `task update --status in_review` when you finish.
|
|
77
|
+
- Never `send` or `mention` the completion report. Those are for intentional targeted escalation or cross-channel notification.
|
|
78
|
+
|
|
79
|
+
## Talking to another participant
|
|
80
|
+
|
|
81
|
+
Asked to mention, ping, notify, or send a short note to someone visible: run `mention` yourself, then confirm what you sent. What notifies them is the visible `<@targetId>` token in the body — naming someone in prose alone does not reach them — and the CLI appends that token when your body leaves it out. If the user says "the other agent" and only one other agent is visible, resolve that id with `users` first.
|
|
82
|
+
|
|
83
|
+
Wanting to collaborate with another agent is the same act — send the short mention or reply-thread note yourself. There is no host-orchestrated protocol to ask for.
|
|
84
|
+
|
|
85
|
+
## Errors
|
|
86
|
+
|
|
87
|
+
A failure prints one `error: …` line on stderr. Exit `2` is a wrong invocation: the request was never sent, so nothing changed.
|
|
88
|
+
|
|
89
|
+
`references/errors.md` maps every gateway error to its cause and its correction, and holds the exit-code contract.
|
|
90
|
+
|
|
91
|
+
## A worked turn
|
|
92
|
+
|
|
93
|
+
You are running in a task thread, you have opened the pull request that implements the task, and you want the reviewer to know.
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
$ borgee-agent --gateway /state/channels/channel-a/.borgee-agent-gateway.json task get
|
|
97
|
+
{
|
|
98
|
+
"id": "task-42",
|
|
99
|
+
"title": "Deliver the daily digest",
|
|
100
|
+
"status": "open",
|
|
101
|
+
"assigneeId": "agent-1",
|
|
102
|
+
"properties": {}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
$ borgee-agent --gateway /state/channels/channel-a/.borgee-agent-gateway.json \
|
|
106
|
+
task set-property --key link.pr --value https://github.com/org/repo/pull/12
|
|
107
|
+
{
|
|
108
|
+
"id": "task-42",
|
|
109
|
+
"properties": { "link.pr": "https://github.com/org/repo/pull/12" }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
$ borgee-agent --gateway /state/channels/channel-a/.borgee-agent-gateway.json \
|
|
113
|
+
task update --status in_progress
|
|
114
|
+
{
|
|
115
|
+
"id": "task-42",
|
|
116
|
+
"status": "in_progress"
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
$ borgee-agent --gateway /state/channels/channel-a/.borgee-agent-gateway.json \
|
|
120
|
+
mention user-7 --body "Digest PR is up for review" --turn-execution-id turn-9f3
|
|
121
|
+
{
|
|
122
|
+
"id": "message-311",
|
|
123
|
+
"body": "Digest PR is up for review <@user-7>"
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Constraints
|
|
128
|
+
|
|
129
|
+
- Local only. The CLI reaches the loopback gateway and nothing else.
|
|
130
|
+
- It does not read or write files anywhere except the one gateway credential file it is handed.
|
|
131
|
+
- Auxiliary sends are short notices — one line, at most twelve words counting the `<@id>` the CLI appends, addressed to someone or attached to a message. They are not a place for the answer.
|
|
132
|
+
- Exactly one auxiliary send per turn, whoever it addresses. A send the gateway rejects does not spend it.
|
|
133
|
+
- The draft is host-private. Read it to see what the host is about to post; never re-post it.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Errors
|
|
2
|
+
|
|
3
|
+
## Exit codes
|
|
4
|
+
|
|
5
|
+
| Code | Meaning |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `0` | The command succeeded; its JSON is on stdout. |
|
|
8
|
+
| `1` | The gateway refused the request or could not be reached. The message carries the HTTP status and the gateway's JSON body. |
|
|
9
|
+
| `2` | A wrong invocation; the message names it. Nothing was sent. |
|
|
10
|
+
|
|
11
|
+
## Gateway errors
|
|
12
|
+
|
|
13
|
+
| Status and error | Cause | Correction |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| 401 `missing_or_invalid_token`, 401 `invalid_token` | The gateway credential file is from an earlier turn; its token has been rotated away. | Re-read the credential path this turn's prompt gives you. |
|
|
16
|
+
| 403 `channel_mismatch` | The task or channel is outside the channel this turn is bound to. | Only this channel is reachable. Work from `task list` in this channel. |
|
|
17
|
+
| 403 `permission_denied` | This agent is not allowed to perform that action in this channel. | Report it; do not retry the same call. |
|
|
18
|
+
| 403 `collaboration_not_enabled` | An auxiliary send on a turn where collaboration is off. | Do not send; put what you wanted to say in your final answer. |
|
|
19
|
+
| 403 `protocol_managed_turn` | An auxiliary send during a host-managed collaboration turn. | The host delivers this turn's reply. Do not send yourself. |
|
|
20
|
+
| 409 `stale_turn_execution_id` | The turn execution id belongs to an earlier turn, or the turn it names has already ended. | Use the turn execution id this turn's prompt carries; never one you remember. |
|
|
21
|
+
| 429 `collaboration_quota_exceeded` | This turn has already spent its one auxiliary send. | Say the rest in your final answer. |
|
|
22
|
+
| 429 `collaboration_target_cooldown` | The same reply target or mention set was addressed moments ago. | Do not repeat it. |
|
|
23
|
+
| 404 `not_found` on `task get` / `task update` / a property command with no task id | You are not inside a task thread, so there is no current task to resolve. | Pass the task id. |
|
|
24
|
+
| 404 `not_found` on a task command with a task id | The task does not exist, or belongs to another channel. | Check the id with `task list`. |
|
|
25
|
+
| 404 `not_found` on `users`, `send`, `mention` | Collaboration is not enabled for this turn, so those commands do not exist. | Do not use them; the turn prompt says when they are live. |
|
|
26
|
+
| 404 `not_found` on `draft` | Either collaboration is not enabled for this turn, or the host holds no draft for it yet — a draft exists only once the turn has produced visible reply text. | Not a verdict on the other collaboration commands: `users`, `send` and `mention` may well answer on this same turn. Carry on and read the draft later if you still need it. |
|
|
27
|
+
| 404 `bootstrap_unavailable` | The host has not published this turn's channel payload yet. | Retry the read once; if it persists, continue without it. |
|
|
28
|
+
| 400 `task_thread_collection_not_allowed` | `task list` or `task create` inside a task thread. | Those belong to the parent channel. |
|
|
29
|
+
| 400 `multiline_message_body_not_allowed`, `message_body_too_verbose` | An auxiliary send must be one line of at most 12 words, and the `<@id>` the CLI appends counts as one of them — each extra `--mention` costs another. | Shorten it to a single-line notice. |
|
|
30
|
+
| 400 `missing_reply_or_mentions` | A send that addresses nobody: no `--reply-to` and no visible mention. | Reply to a message, or mention the participant you mean. |
|
|
31
|
+
| 400 `invalid_status` | `--status` is not one of `open`, `in_progress`, `in_review`, `done`, `cancelled`. | Send one of those five values. |
|
|
32
|
+
| 400 `unknown_property_key` | The property key is not in the registry. | See `task-properties.md` for the registered keys. |
|
|
33
|
+
| 400 `property_value_too_long` | The property value is over 8 KiB. | Store a reference, not a document. |
|
|
34
|
+
| 400 `invalid_json`, `invalid_json_body`, `invalid_message_body`, `deprecated_mentions_not_allowed`, `bad_request`, `missing_turn_execution_id`, `empty_message_body`, `title_required`, `invalid_property_value`, `no_updates`; 403 `browser_origin_not_allowed`; 405 `method_not_allowed` | The request was not the shape, the header set or the invocation the route accepts. | The CLI builds these requests itself and refuses the bad invocations with exit `2` before sending, so reaching one of these means the call was wrapped or rewritten. Run the CLI directly. |
|
|
35
|
+
| 404 `property_not_found` | `task delete-property` for a key the task does not carry. | Read the task's `properties` first. |
|
|
36
|
+
| 413 `request_body_too_large` | An auxiliary send over the 512-byte request cap. | Shorten it. Non-ASCII characters cost several bytes each. |
|
|
37
|
+
| 502 `upstream_error` on a send | Most often a mention of someone who is not a member of this channel: the server refuses the mention, and the gateway has no case for that refusal, so it surfaces as a bare upstream failure. | Drop or correct the mention — `users` spans every channel you belong to, so a participant it lists need not be in this one. Do not repeat the same body. |
|
|
38
|
+
| 502 `upstream_error`, 500 `internal_error` | The gateway reached the server and the call failed there. | On a read, retry once. On a send, take the row above first; a repeat of the same body is not a fix. Report the failure in your answer rather than working around it. |
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Task properties
|
|
2
|
+
|
|
3
|
+
A task property associates a task with something that lives outside it. Use one to record what a reader would otherwise have to hunt for in the thread — the pull request that implements the task, the issue it came from.
|
|
4
|
+
|
|
5
|
+
Read them back with `task get`: every task response carries a `properties` object, `{}` when the task has none.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
borgee-agent --gateway <path> task set-property <task-id> --key link.pr --value https://github.com/org/repo/pull/12
|
|
9
|
+
borgee-agent --gateway <path> task delete-property <task-id> --key link.pr
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The task id is omitted only inside that task's own thread, where the request resolves to the thread's task.
|
|
13
|
+
|
|
14
|
+
## Registered keys
|
|
15
|
+
|
|
16
|
+
The key set is closed; writing an unregistered key is rejected with `unknown_property_key`.
|
|
17
|
+
|
|
18
|
+
| Key | What it holds |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `link.pr` | The pull request that implements this task. Set it as soon as the PR exists, not at the end. |
|
|
21
|
+
| `link.issue` | The issue or ticket the task originates from. |
|
|
22
|
+
| `agent.session_id` | Do not write this. It is registered, so a write is accepted and lands — overwriting the host's record of which provider session worked this task. The host writes it itself after each turn. |
|
|
23
|
+
|
|
24
|
+
## One key per call
|
|
25
|
+
|
|
26
|
+
Each call writes exactly one key, and that is what makes it safe to write a property while another agent writes a different one on the same task: neither write can clobber the other's key.
|
|
27
|
+
|
|
28
|
+
## Value
|
|
29
|
+
|
|
30
|
+
A value is a plain string of at most 8 KiB; a longer one is rejected with `property_value_too_long`. It is a reference — a URL, an identifier — never a document.
|