• TypeScript 97.5%
  • JavaScript 2.3%
  • Dockerfile 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Morten Olsen 5723994014
All checks were successful
ci/woodpecker/push/compliance Pipeline was successful
ci/woodpecker/push/quality Pipeline was successful
ci/woodpecker/push/draft-notes Pipeline was successful
ci/woodpecker/tag/deploy-docs Pipeline was successful
ci/woodpecker/tag/release Pipeline was successful
ci/woodpecker/tag/release-image Pipeline was successful
feat(nlp)!: run a matched intent, and report an honest score
Adds `execute`, taking back the `intent` from a `classify` match, over
`NlpEngine`, `NlpService`, and `POST /api/nlp/execute`.

The response is now an envelope. `score` and `text` describe how the match was
arrived at; `intent` is the executable part and goes back untouched. Deciding
whether a match is strong enough therefore happens exactly once, at the classify
boundary, and `execute` neither wants nor accepts a score to second-guess it with.

The score was already plumbed end to end but carried no information, which is the
more important fix here. nlp.js's own threshold was set to 0.8, and it replaces a
below-threshold intent with `None` *and* rewrites the score to 1 — so a caller
only ever saw scores above the floor, and the engine had already made the decision
for them. Its thresholding is now disabled and the floor applied in
`classifyWith`, with `minScore` overridable per call.

Measuring that turned up something worth recording: the score is honest but not
calibrated, and a threshold does not transfer between hosts. Unrelated input
scores ~0.504 against two slot-bearing intents, ~0.902 once a short slot-free
intent joins them, and ~0.960 when that intent gains phrasings — converging on
what a genuine match scores. Documented in the README with the numbers, and the
guide now tells integrators to probe their own corpus rather than trust the 0.8
default.

An intent raising `ToolInterrupt` answers `status: 'interrupted'` with a 200
rather than a 500, since needing a human is an outcome. It cannot be resumed;
an intent has no resumption channel.

Also reframes the guide's opening. It claimed a provider's actions are mostly
reached by a model composing arguments, which reads as though Grundlag were an
agent framework. Actions are called by whatever is built on top — scripts,
automations, apps, agents — and phrase matching is one more way in, cheap to add
precisely because the catalogue already exists for everything else.

BREAKING CHANGE: `classify` returns `{ intent, score, text }` rather than a flat
match, so `match.id` is now `match.intent.id` and `match.entities` is an
`NlpEntityRegistry` rather than a plain record.
2026-08-22 09:06:27 +02:00
.woodpecker fix(deps): unify fastify to 5.12.1 to repair the type-check 2026-08-20 00:16:57 +02:00
docs feat(nlp)!: run a matched intent, and report an honest score 2026-08-22 09:06:27 +02:00
examples/client feat(core)!: expose entity search and get as agent tools 2026-08-21 21:20:45 +02:00
instance feat(core)!: move persistence from SQLite to Postgres 2026-08-21 22:02:02 +02:00
packages feat(nlp)!: run a matched intent, and report an honest score 2026-08-22 09:06:27 +02:00
providers feat(core)!: move persistence from SQLite to Postgres 2026-08-21 22:02:02 +02:00
scripts feat(core)!: move persistence from SQLite to Postgres 2026-08-21 22:02:02 +02:00
.dockerignore init 2026-07-21 16:59:37 +02:00
.gitignore add documentation 2026-07-21 21:33:02 +02:00
.npmrc fix(build): make the docker image build and start 2026-08-20 08:56:34 +02:00
.prettierignore init 2026-07-21 16:59:37 +02:00
.prettierrc init 2026-07-21 16:59:37 +02:00
AGENTS.md feat(core)!: move persistence from SQLite to Postgres 2026-08-21 22:02:02 +02:00
CLAUDE.md add publish config to home assistant 2026-08-20 09:27:06 +02:00
CONTEXT.md feat(core)!: expose entity search and get as agent tools 2026-08-21 21:20:45 +02:00
CONTRIBUTING.md fix(deps): unify fastify to 5.12.1 to repair the type-check 2026-08-20 00:16:57 +02:00
docker-compose.yaml update docs 2026-07-22 11:46:16 +02:00
Dockerfile fix(build): drop the bundled package managers from the runtime image 2026-08-20 13:52:41 +02:00
eslint.config.mjs ci: add human-gated npm and image release pipeline 2026-08-20 00:10:27 +02:00
LICENSE ci: add human-gated npm and image release pipeline 2026-08-20 00:10:27 +02:00
mise.toml add documentation 2026-07-21 21:33:02 +02:00
package.json ci: add human-gated npm and image release pipeline 2026-08-20 00:10:27 +02:00
pnpm-lock.yaml feat(nlp): add an nlp.js intent classification engine 2026-08-22 00:02:45 +02:00
pnpm-workspace.yaml feat(core)!: move persistence from SQLite to Postgres 2026-08-21 22:02:02 +02:00
Taskfile.yml ci: add human-gated npm and image release pipeline 2026-08-20 00:10:27 +02:00
turbo.json init 2026-07-21 16:59:37 +02:00
vitest.config.ts test: cover the client/server bucket contract, and run examples in CI 2026-08-20 13:47:20 +02:00