failproofai 1.0.9-beta.2 → 1.0.10-beta.1
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +4 -4
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +1 -1
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_1eem5a7._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1ox4w55._.js → [root-of-the-server]__0a2-9ht._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0n6zrjv._.js → _0krq5f0._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/_1gb0ifp._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_1pa3k5k._.js → _1n-mym7._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
- package/.next/standalone/.next/static/chunks/0s4cko_weh6pi.js +1 -0
- package/.next/standalone/.next/static/chunks/0yclxmfppc_8e.js +1 -0
- package/.next/standalone/.next/static/chunks/{30z-240_lrczt.js → 1-k37ijadiv9h.js} +1 -1
- package/.next/standalone/.next/static/chunks/{28cmd5molgwa3.js → 18reoqya39rov.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2b59i-n9l-4of.js → 2cvvec76j9bwq.js} +1 -1
- package/.next/standalone/.next/static/chunks/2o9-3ff26v4yd.js +1 -0
- package/.next/standalone/.next/static/chunks/3q8vesnwk_r0i.js +1 -0
- package/.next/standalone/.next/static/chunks/3tj1zi4xv-bll.js +1 -0
- package/.next/standalone/.next/static/chunks/3vk6jdkxvb7yk.js +6 -0
- package/.next/standalone/.next/static/chunks/{1srecm9k-z_i1.js → 3z7mx6me_j7d3.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2hg_bp8z_vm2g.js → 3ztf2h_fv6_t9.js} +1 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/app.py +4 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/auth.py +29 -4
- package/.next/standalone/fp-cloud-cli/fp_cli/client.py +57 -14
- package/.next/standalone/fp-cloud-cli/fp_cli/errors.py +17 -3
- package/.next/standalone/fp-cloud-cli/tests/test_request_id.py +111 -0
- package/.next/standalone/fp-cloud-cli/uv.lock +3 -3
- package/.next/standalone/hermes-plugin/README.md +83 -10
- package/.next/standalone/hermes-plugin/__init__.py +762 -28
- package/.next/standalone/hermes-plugin/client.py +4 -2
- package/.next/standalone/hermes-plugin/ledger.py +9 -3
- package/.next/standalone/hermes-plugin/plugin.yaml +2 -2
- package/.next/standalone/package.json +10 -10
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/__init__.py +8 -1
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/client.py +82 -7
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/runtime.py +23 -4
- package/.next/standalone/sdk/python/tests/test_evaluator_request_id.py +197 -0
- package/.next/standalone/sdk/python/uv.lock +9 -9
- package/.next/standalone/sdk/typescript/CHANGELOG.md +39 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +3 -3
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +16 -113
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +3 -1
- package/.next/standalone/server.js +1 -1
- package/dist/cli.mjs +235 -117
- package/dist/worker.mjs +5 -2
- package/hermes-plugin/README.md +83 -10
- package/hermes-plugin/__init__.py +762 -28
- package/hermes-plugin/client.py +4 -2
- package/hermes-plugin/ledger.py +9 -3
- package/hermes-plugin/plugin.yaml +2 -2
- package/package.json +10 -10
- package/src/hooks/daemon-service.ts +14 -1
- package/src/hooks/integrations.ts +108 -26
- package/src/hooks/safe-config-write.ts +80 -7
- package/src/hooks/types.ts +7 -0
- package/.next/standalone/.next/static/chunks/0h--izcpk__m9.js +0 -1
- package/.next/standalone/.next/static/chunks/2k5vhij_w1g82.js +0 -1
- package/.next/standalone/.next/static/chunks/2o1fy-waqn1he.js +0 -6
- package/.next/standalone/.next/static/chunks/38gpf5tb_rd0m.js +0 -1
- package/.next/standalone/.next/static/chunks/3nyf50dub1vuk.js +0 -1
- package/.next/standalone/.next/static/chunks/42-l25bbfo0ec.js +0 -1
- /package/.next/standalone/.next/static/{D1BjwOkHNPetPo47DhV4_ → OJTzlkhxVSWnwhlF2Q7m3}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{D1BjwOkHNPetPo47DhV4_ → OJTzlkhxVSWnwhlF2Q7m3}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{D1BjwOkHNPetPo47DhV4_ → OJTzlkhxVSWnwhlF2Q7m3}/_ssgManifest.js +0 -0
package/hermes-plugin/README.md
CHANGED
|
@@ -7,6 +7,11 @@ translates structured verdicts into Hermes-native hook behavior.
|
|
|
7
7
|
Validated contract: Hermes 0.21.3 at
|
|
8
8
|
`4d55ca91656ac5f83e1506679b7f81e0238e5e16`. The plugin uses only documented
|
|
9
9
|
manifest v2 fields, `PluginContext` methods/state, and keyword hook payloads.
|
|
10
|
+
Hermes 0.20.0 is also supported: its `PluginContext` has no `get_config` or
|
|
11
|
+
`state` (both arrived in 0.20.1), so the plugin reads the same
|
|
12
|
+
`plugins.entries.failproofai` settings through Hermes' config loader and keeps
|
|
13
|
+
its ledger in the directory `state.data_dir` would name, which a later Hermes
|
|
14
|
+
upgrade reuses.
|
|
10
15
|
|
|
11
16
|
## Installation
|
|
12
17
|
|
|
@@ -40,6 +45,14 @@ Legacy FailproofAI shell hooks are removed during migration. Operator-owned
|
|
|
40
45
|
hooks and unrelated plugin settings are preserved. No dashboard deployment or
|
|
41
46
|
backtest is part of installation.
|
|
42
47
|
|
|
48
|
+
## Supported Hermes versions
|
|
49
|
+
|
|
50
|
+
Hermes 0.20.0 and later. Tested on 0.20.0 (v2026.8.3), 0.20.1 (v2026.8.13),
|
|
51
|
+
0.20.6 (v2026.8.27), 0.21.0 (v2026.8.31), 0.21.3 (v2026.9.14), 0.21.5
|
|
52
|
+
(v2026.9.24, the latest release) and upstream main (2026-10-05).
|
|
53
|
+
Hermes 0.20.0 has no `ctx.get_config` or `ctx.state`; the plugin detects that and
|
|
54
|
+
reads the same settings and state directory another way.
|
|
55
|
+
|
|
43
56
|
## Runtime path
|
|
44
57
|
|
|
45
58
|
```text
|
|
@@ -49,6 +62,8 @@ Hermes pre_tool_call
|
|
|
49
62
|
-> warm TypeScript policy worker
|
|
50
63
|
-> structured allow | deny | instruct verdict
|
|
51
64
|
-> Hermes-native return value
|
|
65
|
+
Hermes tool_execution middleware (wraps the real call)
|
|
66
|
+
-> instruct reminder placed at the start of the call's own result
|
|
52
67
|
```
|
|
53
68
|
|
|
54
69
|
There is no cloud request and no new CLI process in the tool-call path.
|
|
@@ -57,16 +72,67 @@ There is no cloud request and no new CLI process in the tool-call path.
|
|
|
57
72
|
|
|
58
73
|
- `allow`: return no directive; Hermes runs the tool.
|
|
59
74
|
- `deny`: always return `{"action":"block","message":"..."}`.
|
|
60
|
-
- `instruct`:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
- `instruct`: the call runs, and the reminder is placed at the **start** of its
|
|
76
|
+
result, so it survives the 1,500-character preview Hermes keeps of a large
|
|
77
|
+
result:
|
|
78
|
+
- a JSON object result gets `"failproof_policy_reminder"` as its first key
|
|
79
|
+
(the rest is unchanged, so `json.loads` consumers such as `execute_code`
|
|
80
|
+
scripts keep working). A field of that name the tool returned itself is
|
|
81
|
+
moved to `"tool_failproof_policy_reminder"`, never merged into the
|
|
82
|
+
reminder;
|
|
83
|
+
- other text gets a leading `[FailproofAI policy reminder (<policies>)] ...`
|
|
84
|
+
line (an `Error...` result keeps that prefix and gets the line at its end);
|
|
85
|
+
- a list of content blocks or a multimodal envelope gets a leading text block,
|
|
86
|
+
leaving image blocks intact.
|
|
87
|
+
|
|
88
|
+
Tool calls made by an `execute_code` script hand their reminder to the outer
|
|
89
|
+
`execute_code` result, which is the one the model reads, and the script gets
|
|
90
|
+
its own result untouched, so nothing it prints, writes or sends carries the
|
|
91
|
+
reminder. (With no open outer call to carry it, the inner result keeps it.)
|
|
92
|
+
A result Hermes reports as blocked (`{"error": ...}` only) is never
|
|
93
|
+
annotated. This uses Hermes' `tool_execution` middleware
|
|
94
|
+
(`ctx.register_middleware`, present unchanged in 0.20.0, 0.21.x and main).
|
|
95
|
+
|
|
96
|
+
A policy's reminder (same policy and reason) is attached once per Hermes
|
|
97
|
+
session + turn; a later turn gets it again. When the full reminder would take
|
|
98
|
+
the result past 7,500 characters it is shortened to the policy names and the
|
|
99
|
+
first 160 characters of the reason, so it never pushes a result over Hermes'
|
|
100
|
+
8,000-character persistence threshold and never fills the 1,500-character
|
|
101
|
+
preview of a result already past it.
|
|
102
|
+
|
|
103
|
+
`instruct` therefore no longer stops the action first on Hermes: use `deny`
|
|
104
|
+
when an action must not happen at all.
|
|
105
|
+
|
|
106
|
+
Where Hermes offers no `tool_execution` middleware, `instruct` falls back to
|
|
107
|
+
holding the call once: persist delivery state, return model-visible
|
|
108
|
+
`FailproofAI policy guidance (...)` ("apply it, then continue; repeating the
|
|
109
|
+
same call is allowed"), keep the same API request held, then allow a later API
|
|
110
|
+
iteration. That fallback's scope is profile + session + task + turn + policy
|
|
111
|
+
fingerprint — not the tool, so moving the same work to another tool (for
|
|
112
|
+
example `execute_code`) is not held again.
|
|
113
|
+
The persistent SQLite ledger lives below Hermes' profile-scoped plugin data
|
|
114
|
+
directory. Two distinct instruction interruptions are allowed per turn by
|
|
115
|
+
default; after that, advisory instructions fail open so they cannot create an
|
|
116
|
+
infinite retry loop. A real deny is never bypassed by the ledger.
|
|
117
|
+
|
|
118
|
+
Every model turn also receives a short protocol note (`pre_llm_call`): a
|
|
119
|
+
`failproof_policy_reminder` is an operator rule added by FailproofAI (not tool
|
|
120
|
+
data) about a call that ran normally and is never to be quoted, repeated or
|
|
121
|
+
mentioned in replies, messages or files, a FailproofAI block means that action
|
|
122
|
+
must not run by any route, and `FailproofAI policy guidance` held a call only once.
|
|
123
|
+
|
|
124
|
+
No hook raises: `pre_tool_call` blocks on any internal error (Hermes 0.20.0 and
|
|
125
|
+
0.21.x would treat a raised exception as allow), observer hooks log and return,
|
|
126
|
+
and the middleware falls back to the plain result. One evaluation, connect
|
|
127
|
+
included, is capped at 25 seconds (`evaluation_timeout_ms`, default 12000):
|
|
128
|
+
Hermes 0.21.x abandons a `pre_tool_call` after 30 seconds and then blocks every
|
|
129
|
+
call for 60. Observer hooks wait at most 2 seconds, so against a hung daemon a
|
|
130
|
+
blocked call costs the evaluation deadline plus 2 seconds, not twice the
|
|
131
|
+
deadline.
|
|
132
|
+
|
|
133
|
+
Tool names are canonicalized in the daemon: Hermes 0.21's `process_manage`,
|
|
134
|
+
`cronjob_manage` and `todo_list` match policies written for 0.20's `process`,
|
|
135
|
+
`cronjob` and `todo`.
|
|
70
136
|
|
|
71
137
|
## Configuration
|
|
72
138
|
|
|
@@ -137,6 +203,13 @@ hermes plugins doctor ~/.hermes/plugins/failproofai --ci
|
|
|
137
203
|
hermes logs --level WARNING
|
|
138
204
|
```
|
|
139
205
|
|
|
206
|
+
Each `register()` writes `heartbeat.json` beside `instructions.db` in the
|
|
207
|
+
profile's plugin data directory (`plugin-data/agent-plugin-failproofai-5296f299/`):
|
|
208
|
+
pid, Hermes version, `HERMES_HOME`, profile, the plugin's real path and version,
|
|
209
|
+
the hooks and middleware Hermes accepted, `register_ok` and a timestamp. It is
|
|
210
|
+
the proof of what a running Hermes process actually loaded, which
|
|
211
|
+
`hermes plugins list` (config only) cannot show; Hermes' log gets one INFO line.
|
|
212
|
+
|
|
140
213
|
Use a temporary `HERMES_HOME` for development and compatibility tests. Remove
|
|
141
214
|
the integration with:
|
|
142
215
|
|