@ouro.bot/cli 0.1.0-alpha.851 → 0.1.0-alpha.852
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/changelog.json
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.852",
|
|
6
|
+
"changes": [
|
|
7
|
+
"An orientation hold no longer blocks read-only tools from the agent's own MCP servers (readOnlyHint); the Butler's media lookups are marked read-only. The media tools treat a 200 with an empty body as success, so clearing a stuck download goes on to re-search"
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.851",
|
|
6
12
|
"changes": [
|
|
@@ -63,7 +63,9 @@ async function req(base, path, { key, header = "X-Api-Key", method = "GET", body
|
|
|
63
63
|
throw new ServiceError(`${serviceOf(base)}_http_${res.status}`, `${serviceOf(base)} returned ${res.status}${text ? `: ${text.slice(0, 200)}` : ""}`)
|
|
64
64
|
}
|
|
65
65
|
if (res.status === 204) return null
|
|
66
|
-
|
|
66
|
+
// Sonarr/Radarr answer some DELETEs with 200 and an empty body; that is success, not a parse failure.
|
|
67
|
+
const raw = await res.text()
|
|
68
|
+
return raw.trim() ? JSON.parse(raw) : null
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
function serviceOf(base) {
|
|
@@ -1135,9 +1137,10 @@ export async function mediaManualImport(a) {
|
|
|
1135
1137
|
|
|
1136
1138
|
// ------------------------------------------------------------------- schema
|
|
1137
1139
|
|
|
1138
|
-
const TOOLS = [
|
|
1140
|
+
export const TOOLS = [
|
|
1139
1141
|
{
|
|
1140
1142
|
name: "media_search",
|
|
1143
|
+
annotations: { readOnlyHint: true },
|
|
1141
1144
|
description: "Search or browse the household media catalogue. Use `query` for a title lookup: partial and misspelled titles are matched against the library first (Sonarr, Radarr, Jellyfin) and returned as `library_matches` with their kind and service id, and when nothing in the library matches, `lookup_candidates` (TVDB/TMDB) cover titles not in the library. Never say a title does not exist without reading both; use `genres`/`keywords`/`year_range` to browse by vibe (e.g. keywords ['autumn','thanksgiving'] for cozy fall films). `on_shelf: true` restricts to what is already downloaded, `false` to what is not, omit for both. Every item says whether it is on the shelf and carries its tmdb_id so a follow-up media_request needs no second lookup.",
|
|
1142
1145
|
inputSchema: { type: "object", properties: {
|
|
1143
1146
|
query: { type: "string", description: "Title or free text. Omit to browse by filters." },
|
|
@@ -1163,6 +1166,7 @@ const TOOLS = [
|
|
|
1163
1166
|
},
|
|
1164
1167
|
{
|
|
1165
1168
|
name: "media_request_status",
|
|
1169
|
+
annotations: { readOnlyHint: true },
|
|
1166
1170
|
description: "One call, every stage: request, indexer search, download, file on disk, plus acquisition-chain health and a deterministic `diagnosis` block naming what is stuck, why, and the fix. Use this for any 'is it here yet?' or 'why hasn't X downloaded?' question. A queue row is not proof of progress: a release sitting at zero bytes comes back as stalled, not as downloading. Never infer the cause yourself — read diagnosis.summary.",
|
|
1167
1171
|
inputSchema: { type: "object", properties: {
|
|
1168
1172
|
request_id: { type: "string", description: "e.g. jellyseerr:42" },
|
|
@@ -1181,6 +1185,7 @@ const TOOLS = [
|
|
|
1181
1185
|
},
|
|
1182
1186
|
{
|
|
1183
1187
|
name: "media_chain_health",
|
|
1188
|
+
annotations: { readOnlyHint: true },
|
|
1184
1189
|
description: "Health of the whole acquisition chain: Prowlarr indexers, their failure state, and whether Prowlarr is syncing to Sonarr/Radarr. Call this when several things are stuck at once, or before telling anyone a specific title is the problem — a dead chain blocks everything and is the single most likely cause.",
|
|
1185
1190
|
inputSchema: { type: "object", properties: {} },
|
|
1186
1191
|
},
|
|
@@ -1213,6 +1218,7 @@ const TOOLS = [
|
|
|
1213
1218
|
},
|
|
1214
1219
|
{
|
|
1215
1220
|
name: "media_episodes",
|
|
1221
|
+
annotations: { readOnlyHint: true },
|
|
1216
1222
|
description: "List a Sonarr series' episodes (optionally one season): episode_id, SxxEyy code, scene_code (the numbering release names use, when Sonarr has a mapping), title, air date, has_file. Use it to see what the TVDB numbering calls each episode before searching for releases by hand.",
|
|
1217
1223
|
inputSchema: { type: "object", properties: {
|
|
1218
1224
|
service_id: { type: "number", description: "Sonarr series id." },
|
|
@@ -1221,6 +1227,7 @@ const TOOLS = [
|
|
|
1221
1227
|
},
|
|
1222
1228
|
{
|
|
1223
1229
|
name: "media_indexer_search",
|
|
1230
|
+
annotations: { readOnlyHint: true },
|
|
1224
1231
|
description: "Free-text search across every indexer (Prowlarr), sorted by seeders. Discovery only, it grabs nothing. Use it when Sonarr/Radarr's own search finds nothing: try the scene code from media_episodes, 'Season N', the year, or an episode title, to learn whether any release exists and how it is named. Zero seeders means it cannot download right now.",
|
|
1225
1232
|
inputSchema: { type: "object", properties: {
|
|
1226
1233
|
query: { type: "string" },
|
|
@@ -1229,6 +1236,7 @@ const TOOLS = [
|
|
|
1229
1236
|
},
|
|
1230
1237
|
{
|
|
1231
1238
|
name: "media_release_search",
|
|
1239
|
+
annotations: { readOnlyHint: true },
|
|
1232
1240
|
description: "Interactive release search for a series or movie already in the library: what the indexers offer and how Sonarr/Radarr parsed each release (full_season, parsed_season, parsed_episodes, mapped_episodes), whether it is rejected and why, and whether it is blocklisted. Series: give season_number or episode_ids. Can take a minute or more. `query` filters returned titles. Use it when the automatic search found nothing, then grab with media_release_grab.",
|
|
1233
1241
|
inputSchema: { type: "object", properties: {
|
|
1234
1242
|
kind: { type: "string", enum: ["series", "movie"] },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<?xml version="1.0"?>
|
|
2
2
|
<Container version="2">
|
|
3
3
|
<Name>ouro-butler</Name>
|
|
4
|
-
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.
|
|
4
|
+
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.852</Repository>
|
|
5
5
|
<Registry>https://github.com/ourostack/ouroboros/pkgs/container/ouroboros-butler</Registry>
|
|
6
6
|
<Network>host</Network>
|
|
7
7
|
<Shell>sh</Shell>
|
|
@@ -67,11 +67,15 @@ function mcpToolsAsDefinitions(view) {
|
|
|
67
67
|
});
|
|
68
68
|
return {
|
|
69
69
|
tool: schema,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
reason: "
|
|
74
|
-
|
|
70
|
+
// A read-only hint is trusted only from the agent's own bundle (agent.json mcpServers),
|
|
71
|
+
// so an orientation hold still lets the agent inspect through those tools.
|
|
72
|
+
riskProfile: entry.source === "builtin" && tool.annotations?.readOnlyHint === true
|
|
73
|
+
? { mutates: "none", risk: "low", reason: "read-only tool from the agent's own MCP server" }
|
|
74
|
+
: {
|
|
75
|
+
mutates: "external_side_effect",
|
|
76
|
+
risk: "high",
|
|
77
|
+
reason: "MCP tools may mutate external systems",
|
|
78
|
+
},
|
|
75
79
|
handler: async (args, ctx) => {
|
|
76
80
|
if (ctx?.agentName !== binding.agentName || ctx.agentRoot !== binding.agentRoot) {
|
|
77
81
|
(0, runtime_1.emitNervesEvent)({
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.852",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@ouro.bot/cli",
|
|
9
|
-
"version": "0.1.0-alpha.
|
|
9
|
+
"version": "0.1.0-alpha.852",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
12
12
|
"@azure/identity": "^4.13.0",
|