Commit Graph

4286 Commits

Author SHA1 Message Date
RockChinQ b51a448b1e feat: stateless certified shared worker
Implements stateless singleton component model for certified shared Workers, integrating with SDK 0.7.0.
2026-09-28 13:25:40 +08:00
RockChinQ e778445982 feat: add beta environment banner
Add beta environment warning banner for Cloud beta deployments with i18n support (zh/en/ja)
2026-09-28 13:17:03 +08:00
Type_rBody a75e57ade3 Merge pull request #2579 from langbot-app/feat/workspace-operation-traceability
Feat/workspace operation traceability
2026-09-28 02:27:56 +08:00
TyperBody 280be0d7a4 fix(operation-trace): audit every route for misclassified mutations
Systematically cross-checked all 263 route/method pairs against the classifier
and fixed every case where a real change could be mislabelled:

- POST /skills and PUT /skills/<name> were classified as skill_view (read
  bucket), so creating or editing a skill was silently unlogged at the mutation
  level. They now record skill_update.
- The public webhook ingress (/bots/<uuid>) and the embedded chat widget
  (/embed/*) are unauthenticated visitor traffic, not Workspace changes; they
  are dropped instead of logged as create/resource.
- Uploading files and indexing documents (data flowing into a resource) are
  offered as observations so they never fill the log; deleting a knowledge-base
  file is destructive and now records file_delete.
- A plugin's own config-file edit/delete is a plugin change, not an opaque
  resource delete; ordered before the /config rule that also matched it.
- The bucket now comes from the action table (plus 'a read verb is always a
  read'), so a write action can no longer be forced into the read bucket.
- Added agents and files resource families; localized every new action/resource
  type in all nine locales.
2026-09-28 02:17:50 +08:00
TyperBody 67ff4d3054 fix(operation-trace): record uninstalls and deletes, drop assistant chatter
- Split the route rules on the HTTP method so a DELETE is classified as a
  destructive action instead of falling into the read/write bucket. Uninstalling
  a plugin or skill and deleting a knowledge base or MCP server were recorded as
  a view/update and left no readable trace.
- Add plugin_uninstall, skill_uninstall, knowledge_base_delete and mcp_delete.
- Skip the assistant's own conversation traffic: a chat session produced opaque
  create/resource rows that answered nothing.
- Localize the new actions and the assistant_conversation resource type in all locales.
- Sync the assistant tool action list and apply ruff formatting.
2026-09-28 02:06:57 +08:00
TyperBody b0fab2386e Merge remote-tracking branch 'origin/master' into feat/workspace-operation-traceability 2026-09-28 01:56:03 +08:00
TyperBody 7eeb0393a6 feat(operation-trace): collapsible retention policy and assistant trace tool
- Collapse the retention policy section by default, showing a one-line summary when collapsed.
- Add the owner/admin-only list_operation_logs assistant tool backed by audit.view.
- Enforce per-tool permissions on both tool listing and invocation.
- Add a substring search filter (search) to query_logs and the tool so callers can
  ask narrow questions (plugin name, account, verb) instead of dumping the full history.
- Project records to a compact shape so a page stays under the assistant result budget.
- Localize the new assistant tool label and retention summary across all locales.
2026-09-28 01:56:00 +08:00
TyperBody 9ecb469d13 feat(operation-trace): lead with the change, fix pipeline extension tracing
The panel answered "who, when, what" poorly: the actual before → after diff
was hidden behind a click, the actor was a muted line, and a whole row went to
the route while duration and hash sat in a permanent right column. The data
already arrives with the page, so the panel now reads top-down in the order an
operator actually looks:

* who and when first, then the action and resource, then the diff spelled out
  inline (long values collapse to their size so a pipeline config does not
  render as two near-identical blobs), with route / method / status / duration
  / evidence hash moved into the expanded diagnostics line;
* the whole card is the expand toggle with a rotating chevron, which removes
  the ambiguity of a small text link whose expanded state looked identical;
* records are bucketed into today / yesterday / dated groups so a long history
  reads as a timeline;
* a "changes only" toggle (reusing the level filter) answers "who changed
  something" in one click -- in the live log 489 of 499 rows are pure views,
  so this is the difference between a haystack and the ten rows that matter.

Tracing fixes found while reading the live log:

* PUT /pipelines/<uuid>/extensions was classified as a plugin config change
  because the generic ('/extensions') rule ran first; it now maps to a
  pipeline-specific action;
* that handler recorded no diff at all, so "modified extension config" could
  never say what changed. It now captures the previous bindings and reports the
  before → after.

Cache: the integrity result is now keyed by (Workspace, listing filters) so
each view reuses its own verification, and a delete invalidates all views for
the Workspace. Fourteen tests cover the projection, the verifier, the cache
lifecycle and the failure modes.
2026-09-28 01:03:02 +08:00
TyperBody ed93e7f1ac perf(operation-trace): project hash columns and make the integrity cache safe
The integrity scan selected whole rows, so a cold pass paged in the
changes/detail payloads and the client fingerprint for up to
MAX_INTEGRITY_SCAN_ROWS rows the verifier never reads. Project only the hash
columns, and add a lightweight verifier so the scan no longer builds a full
display dict per row.

Repair the read cache so it is a latency shield, not a correctness shortcut:
a result computed within INTEGRITY_CACHE_TTL_SECONDS is served from the
per-Workspace cache (opening, refreshing and paging all land inside that
window and pay nothing), while a cache miss re-verifies the whole window. An
incremental scan that skips previously verified ids can never see an edit to
an already-cached row -- exactly the tampering this feature exists to expose.
Verified against a live 414-row log: 50 content edits and 7 re-signed links
are all detected, including an edit to a row verified on a previous pass.

Also fix two correctness gaps and one maintenance bug:
- age-based prune deleted rows without invalidating the cached prefix;
- the boundary baseline is now read only when the history exceeds the scan
  window, which a bounded scan makes the rare case;
- the operation-log retention block had drifted outside the per-binding loop
  in the maintenance task, so only the last discovered Workspace was ever
  pruned while the others grew unbounded.

Tests: scan projection, verifier parity, TTL cache reuse, cache-miss
re-verification, edit to an already-verified row, hash mismatch, chain break
and prune invalidation.
2026-09-27 23:43:51 +08:00
TyperBody 7e8daa1c14 perf(operation-trace): cache and incrementally verify the integrity scan
Reading the panel re-hashed up to MAX_INTEGRITY_SCAN_ROWS (20000) rows on
every open, refresh and page turn -- measured ~280ms for 385 rows, growing
linearly with history -- which is what made the log feel slow. The chain is
append-only, so a verified prefix stays valid: keep a per-Workspace cache and,
once warm, verify only the rows appended since (bounded window), reusing the
prior result across reads. Deletions (prune / row budget) invalidate it.

Also fix the cache-hit path (it referenced a field that was never stored) and
the "scanned" count (it double-counted reused rows).

Measured on 385 rows: cold ~280ms -> warm ~0.7ms -> incremental ~15ms.
2026-09-27 23:00:56 +08:00
huanghuoguoguo 4f00878a83 Merge pull request #2601 from langbot-app/feat/cli-core-integrated
feat(api): support CLI diagnostics and Pipeline runs
2026-09-27 18:04:12 +08:00
huanghuoguoguo 4f95016998 test(api): align CLI diagnostics with integration gates 2026-09-27 17:46:19 +08:00
huanghuoguoguo 07f3283abf feat(api): enable CLI diagnostics on current master 2026-09-27 17:31:06 +08:00
RockChinQ ac366193bc Merge pull request #2600 from langbot-app/fix/pin-sdk-0.6.20
chore(plugin): pin SDK 0.6.20
2026-09-27 17:08:39 +08:00
RockChinQ 3b94b7e4cc chore(plugin): pin SDK 0.6.20 2026-09-27 09:00:36 +00:00
RockChinQ 10bd175944 Merge pull request #2599 from langbot-app/fix/pin-sdk-0.6.19
chore(plugin): pin SDK 0.6.19
2026-09-27 15:50:14 +08:00
RockChinQ 0b78617b82 chore(plugin): pin SDK 0.6.19 2026-09-27 07:42:02 +00:00
RockChinQ d7ccb71dab Merge pull request #2598 from langbot-app/fix/pin-sdk-0.6.18
chore(plugin): pin SDK 0.6.18
2026-09-27 14:44:57 +08:00
RockChinQ cbc8ef2324 chore(plugin): pin SDK 0.6.18 2026-09-27 06:36:21 +00:00
RockChinQ 58c1b8ee4f Merge pull request #2597 from langbot-app/fix/pin-sdk-0.6.17
chore(plugin): pin SDK 0.6.17
2026-09-27 13:48:23 +08:00
RockChinQ b06083d9b6 chore(plugin): pin SDK 0.6.17 2026-09-27 05:36:56 +00:00
RockChinQ 30e7d9409e Merge pull request #2596 from langbot-app/dev/shared-worker-local-e2e
chore(plugin): pin SDK 0.6.16
2026-09-27 12:53:21 +08:00
RockChinQ c7306dc8b2 chore(plugin): pin SDK 0.6.16 2026-09-27 04:38:11 +00:00
RockChinQ 16d3ac58b8 Merge pull request #2595 from langbot-app/fix/pin-sdk-0.6.15
fix(plugin): pin SDK 0.6.15
2026-09-27 11:07:49 +08:00
RockChinQ 6da0aea901 fix(plugin): pin SDK 0.6.15 2026-09-27 02:59:40 +00:00
huanghuoguoguo 6a1cc49c54 docs(agent): document standalone LangBot CLI (#2571) 2026-09-27 10:27:48 +08:00
RockChinQ 718fa771e4 Merge pull request #2594 from langbot-app/fix/shared-install-readiness-final
fix(plugin): bound shared install readiness
2026-09-27 09:03:26 +08:00
RockChinQ d1a0ae9b26 fix(plugin): bound shared install readiness 2026-09-27 00:55:58 +00:00
RockChinQ e77f66d22c Merge pull request #2593 from langbot-app/fix/pin-sdk-0.6.14
fix(plugin): pin SDK 0.6.14 and bound shared readiness
2026-09-27 08:25:38 +08:00
RockChinQ 765dac74ea fix(plugin): pin SDK 0.6.14 and bound shared readiness 2026-09-27 00:11:57 +00:00
RockChinQ bd8eaf3123 Merge pull request #2591 from langbot-app/fix/pin-sdk-0.6.13
chore(runtime): pin plugin SDK 0.6.13
2026-09-27 05:38:07 +08:00
RockChinQ 3d6a203724 chore(runtime): pin plugin SDK 0.6.13 2026-09-26 21:28:52 +00:00
RockChinQ a0cab74ea7 Merge pull request #2590 from langbot-app/fix/pin-sdk-0.6.12
chore(runtime): pin plugin SDK 0.6.12
2026-09-27 04:50:46 +08:00
RockChinQ e63fcb36e4 chore(runtime): pin plugin SDK 0.6.12 2026-09-26 20:42:15 +00:00
TyperBody 1488dd3924 chore(operation-trace): rebase migration onto master head, drop unused import
The pull request merge produced two Alembic heads: this branch's
0032_operation_traceability and master's 0032_cert_artifact_digest both
descended from 0031_merge_totp_assistant, so the integration and migration
jobs failed with "Multiple head revisions". Renumber the traceability
migration to 0033 and point it at master's head (0032_cert_artifact_digest),
restoring a single linear head.

Also replace the noqa'd unused import of the traceability routes with an
importlib bootstrap (addresses the CodeQL unused-import finding) and merge
origin/master to pick up the certification digest backfill.
2026-09-27 02:50:28 +08:00
TyperBody 7eac330f33 Merge remote-tracking branch 'origin/master' into feat/workspace-operation-traceability 2026-09-27 02:46:00 +08:00
TyperBody a8daa99884 fix(operation-trace): repair pageOf key placement, numbered pager, right column
- pageOf was inserted under the wrong namespace (the locale files already had a
  hideDetails in toolCalls), so the UI rendered the raw key. Removed it and
  replaced the dropdown with a numbered pager (first/last always visible, a
  one-page window around the current page, gaps as an ellipsis).
- Restore the right-hand column (duration + record hash) that the previous
  declutter removed; the digest is still opt-in, but the hash stays visible.
- Hide the status code on success: a 200 is the default, so only >=400 shows.
2026-09-27 02:39:09 +08:00
TyperBody 67bc80e3bc feat(operation-trace): declutter the log list and add page navigation
The list was noisy and hard to read: a constant "verified" badge and the
"L1/L2" level badge on every row carried no information, the same "view X"
line repeated until it buried real changes, and each row rendered its full
payload diff inline.

- Drop the per-row level badge and the "verified" badge; keep only an
  exception badge, so a healthy row shows nothing extra.
- Collapse consecutive identical rows into one line with an "xN" count.
- Make the change digest opt-in per row (one expanded at a time) and show a
  "<n> changes" toggle instead of dumping the diff.
- Show the registered route under each row so "Resource / System" is no
  longer ambiguous about what actually happened.
- Replace the arrows-only pager with a page selector ("Page x / y") plus the
  arrows, for logs with hundreds of records.

Verified: tsc, eslint, prettier and check-i18n all pass.
2026-09-27 02:32:12 +08:00
RockChinQ 7c282964c8 Merge pull request #2589 from langbot-app/fix/pin-sdk-0.6.11
chore(runtime): pin plugin SDK 0.6.11
2026-09-27 02:29:52 +08:00
RockChinQ 755149ab0a chore(runtime): pin plugin SDK 0.6.11 2026-09-26 18:16:39 +00:00
TyperBody 884beea4b6 perf(operation-trace): move all trace persistence off the request path
Tracing ran inline with the request: every traced call did several database
round trips (dedupe probe, actor-name lookup, newest-hash read) and a
serialized insert. With tracing on, the WebUI's burst of parallel requests
(login alone touches a dozen endpoints) saturated the write path and stalled
the whole service.

Now the request path only builds a bounded dict and pushes it onto a queue
(measured ~0.005ms per trace, zero database work). A single background writer
coroutine drains the queue and persists sequentially, which also removes the
read-newest-hash race that used to produce false "chain broken" reports; the
previous asyncio lock is gone. The actor display-name lookup and the dedupe
key hash move into the writer as well. The queue is bounded: when traffic
outruns the writer the oldest pending trace is dropped instead of slowing the
request down.

Verified: migration tests pass, ruff clean, a focused writer test shows
enqueue is non-blocking, rows link with zero chain breaks and no internal
key leaks into the stored row.
2026-09-27 02:16:26 +08:00
RockChinQ 8a55781f02 Merge pull request #2588 from langbot-app/fix/pin-sdk-0.6.10
chore(runtime): pin plugin SDK 0.6.10
2026-09-27 01:23:02 +08:00
RockChinQ 3493660f5e chore(runtime): pin plugin SDK 0.6.10 2026-09-26 17:08:51 +00:00
TyperBody a4f89cf28f fix(operation-trace): stop false tamper reports and sharpen resource classification
- Chain integrity: the "read newest hash, then insert" pair in record() could be
  interleaved by concurrent traces (the panel opens a dozen parallel GETs), so two
  rows linked to the same predecessor and one looked like a broken chain even
  though nobody edited anything. Serialize the pair with a per-service lock.
- Resource classification: generic verbs fell back to resource_type='resource', so
  almost every read showed up as "View resource / Resource" (pipelines, bots,
  providers, users, monitoring...). Derive the family from the registered route
  identity (pipeline, bot, model_provider, llm_model, monitoring, user, workspace,
  webhook, api_key, system).
- Frontend: render the resource family for the new types (8 locales) and keep the
  resource_id badge added earlier.

Verified: backend integration 358 passed, ruff check/format clean; frontend tsc,
eslint, prettier and check-i18n all pass.
2026-09-27 00:45:55 +08:00
TyperBody 9964f284e1 refactor(operation-trace): isolate subsystem, fix install identity, merge migrations
- Move the operation-traceability service and its HTTP routes into a standalone
  pkg/operation_trace package; the Core controller package no longer depends on it
  (routes stay auto-discovered by the controller package scan).
- Gate the hot path on one module-level boolean exposed as ap.operation_trace_active:
  while no Workspace has tracing enabled the route wrapper performs zero trace work
  and zero database round trips. The gate opens when a Workspace enables tracing and
  is primed once at startup for already-enabled Workspaces.
- Record the installed extension identity for GitHub / marketplace / local / upload
  installs (owner/repo, author/name, filename) so the trace no longer shows a
  nameless "a plugin was installed" event and the card names the extension.
- Merge migrations 0032 + 0033 into a single 0032_operation_traceability revision
  carrying the full table shape and an index set that matches the ORM.

Tests: unit 5165 passed / integration 358 passed; ruff check + format clean.
2026-09-27 00:11:57 +08:00
RockChinQ 5e21d02ce4 Merge pull request #2587 from langbot-app/fix/pin-sdk-0.6.9
chore(runtime): pin plugin SDK 0.6.9
2026-09-26 22:46:54 +08:00
RockChinQ 64dc04d848 chore(runtime): pin plugin SDK 0.6.9 2026-09-26 14:33:35 +00:00
RockChinQ 81c38be0af Merge pull request #2586 from langbot-app/fix/pin-sdk-0.6.8
chore(runtime): pin plugin SDK 0.6.8
2026-09-26 21:11:34 +08:00
RockChinQ ccbf7c226e chore(runtime): pin plugin SDK 0.6.8 2026-09-26 13:02:43 +00:00
RockChinQ 2356086550 Merge pull request #2585 from langbot-app/fix/pin-sdk-0.6.7
fix(plugin): pin runtime SDK 0.6.7
2026-09-26 14:26:42 +08:00