Skip to content

Tree: model-based clustering for roles the rules cannot place - #520

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:feat/tree-model-cluster
Oct 21, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:feat/tree-model-cluster

Conversation

@HugoXK

@HugoXK HugoXK commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Tree: model-based clustering for roles the rules cannot place

Part of #450 (item 2)

The tree's self-organization (src/roles.js) places a Bot by the words in its name, role label and description. A role the small vocabulary does not hold finds no group and the Bot stays outside the tree. With modelClassify: true in the tree config — and the host allow-listing flybot-tree in flybot.modelPlugins — a Bot the rules cannot place is sent once to the sanctioned plugin model call (#518) for a single category, stored on the Bot as modelDomain, and read by roles.js only where the vocabulary found none, so the deterministic grouping stays primary.

Off by default, one call per role change (fingerprinted), a refused or unparsable answer stores nothing and never clears a good label, and the host's caps bound every call. Plugin only: without the model seam (flybot.model.ask) the plugin falls back to the current rules and asks nothing.

Ran at the tip: npm run verify (green, TZ=UTC), node scripts/lint-plugins.mjs tree (0 errors). Not run: smoke, Desktop, real-model steward.

@Birfy

Birfy commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

Review (Birfy, 2026-10-20 16:05 Asia/Shanghai) at 38ec202. CI green on this tip.

Design: Matches #450 item 2 and owner tree rules — opt-in twice (modelClassify + host allow-list), rules primary / model only fills a missing domain, fingerprint so one ask per role change, refused/unparsable never clears a good label, stores a category id (modelDomain) not message text. Adapter askModel feature-detects older cores. English docs/README.

Stack: Needs #518 (flybot.model.ask) merged (or available) first; without it askModel returns no-api and the plugin stays on rules — safe degrade.

Nits: first opt-in run classifies every non-root tree Bot (host 30/min cap bounds it). parseDomain("none") stores domain: null which roles.js ignores (string check) — fine.

No design conflict found. Not self-PASS (HugoXK PR; owner has not confirmed accepting #520). See confirmation on #519.

@github-actions github-actions Bot added the risk:T2 Risk tier T2 (host/plugin code or an unnamed path), set by the controller from the diff label Oct 20, 2026
@HugoXK

HugoXK commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — the nits are noted and left as-is by design: the first opt-in run classifies each non-root tree Bot once, bounded by the host's 30/min cap, and parseDomain("none") stores domain: null which roles.js ignores (it only applies a valid id). Stacked on #518; it stays on rules until that seam is available.

@Birfy

Birfy commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

This PR conflicts with main (dirty).

Please merge main into the branch, re-run npm run verify, and regenerate the patches/ds-bot/ mirror if any core/ file changed.

…lowLab#450)

With modelClassify: true AND the host allow-listing the plugin, a tree
Bot whose role the deterministic vocabulary cannot map is sent once to
the sanctioned plugin model call (ThinkFlowLab#518) for a single category, stored on
the Bot as modelDomain and read by roles.js only where the vocabulary
found none. Off by default, one call per role change, rules stay primary.
@HugoXK
HugoXK force-pushed the feat/tree-model-cluster branch from 38ec202 to 7a7844d Compare October 21, 2026 01:23

@Birfy Birfy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: PASS at 7a7844d

Tip SHA: 7a7844d9fc7a65693911c4ef11db1d7c06541d47
The author rebased it onto current main, so it merges cleanly now; this is the first PASS at this tip (the earlier note at 38ec2029 no longer applies).
Read the whole 10-file diff: classify-model.js (61 lines — opt-in twice: config.modelClassify AND the host allow-list flybot.modelPlugins; one ask per role-text fingerprint; stored in the Bot field modelDomain { domain, fp, at }; a refused or unparsable answer stores nothing and never clears a good label; rules still win because roles.js applies the model domain only when the vocabulary found none), the adapter seam askModel (absent seam answers no-api instead of reaching into the host), index.js scheduling (3 s / 20 s then every 30 min, unref'd, disposed with the plugin; host caps 30/min bound it), the docs (tree.md section + roles/classify-model rows), README config comment, changelog fragment and the mock-flybot model seam plus 6 new tests.
Checked the host contract it relies on: core/src/host/plugin-model.js exposes model.ask(plugin, input) as { ok, text } / { ok, code } with an allow-list, a read-only refusal and per-minute caps, and hooks.js binds the plugin id — the call in adapter.js matches that shape, and the plugin sends only the role text (never message content).
Ran at the tip: CI tests-ok green (test, plugins tree/social/timeline, package all success at this SHA). In a copy of current main with this diff applied: plugins/tree 89/89 tests, scripts/lint-plugins.mjs tree finished with 0 errors, changelog.mjs check OK.
Not run: one-shot npm run verify (2 GiB OOM), core suite, arch-docs on this copy, smoke, Desktop, real-model call (no provider in this container).

Tier: T2 (plugins/tree/src/**). Awaiting the owner's click in the GitHub UI plus this PASS at the tip. Any new commit voids this PASS. It stays opt-in and off by default.

@Birfy Birfy added the awaiting-approval PR is green and waits for the maintainer's approval (T2/T3) or a review PASS at its tip label Oct 21, 2026
@Birfy
Birfy added this pull request to the merge queue Oct 21, 2026
Merged via the queue into ThinkFlowLab:main with commit f893134 Oct 21, 2026
8 checks passed
@Birfy Birfy removed the awaiting-approval PR is green and waits for the maintainer's approval (T2/T3) or a review PASS at its tip label Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:automation Scheduled tasks and automation enhancement New feature or request risk:T2 Risk tier T2 (host/plugin code or an unnamed path), set by the controller from the diff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants