Replace copied workflow logic with the strict orb-owned QBit profile.
Preserve publication opt-outs and full Maven verification.
Co-Authored-By: OpenAI Codex <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
Preserve current attachment, notification and starter prompt behavior. Encrypt user titles that resemble ciphertext unless they match the same stored record; verify all eight reactor modules.
Co-Authored-By: Codex <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
Cap combined prompts at three and remove cached authorization-sensitive suggestions. Preserve bounded deterministic generation and cover field, row, table, policy and history changes. Thirty focused tests passed.
Co-Authored-By: Codex <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
Preserve field visibility filtering while interpreting the actual API response shape. Verified allowed fields and hidden/password exclusions through the real endpoint.
Co-Authored-By: Codex <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
Preserve both attachment and notification behavior. Full eight-module verify and 45 focused turn, notification, bulk-load and attachment tests passed.
Co-Authored-By: Codex <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
Decode images within frame and pixel limits before provider use, contain malformed attachments per file, and preserve the host PDFBox font mapper.
Co-Authored-By: Codex <noreply@openai.com>
Signed-off-by: James Maes <james@kof22.com>
The turn engine reads pageContext.attachments through AttachmentService and
inlines the framed content (and images for vision models) into the
question's user message, after both cached system blocks. Unreadable files
become notices; image parts are dropped before a call to a model without
vision. In HIPAA mode attachments count as PHI. The system prompt treats
uploaded_file blocks as data and tells the model to propose writes with
create_record/update_record instead of saying it cannot create records.
GET /config reports features.attachments and the attachment limits.
Adds end-to-end, PHI routing and red-team tests.
Part of KofTwentyTwo/Website-Backend#305
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
assistant_conversation is open to every assistant user (assistant.hasAccess
or assistant.admin) through AssistantAccessPermissionChecker; rows stay
locked to their owner, and the Assistant app and other tables stay
admin-only. A conversation customizer limits user edits to title, pinned
and status, refuses deleting a conversation with an answer in progress and
deletes the child rows after a table delete, through the same store code
as DELETE /conversations/{id}.
Adds Archive, Restore and Delete conversations as standard streamed-ETL
record actions on the table, acting only on rows the user can see.
UI API extension assistant 1.6.0: conversation list items have running,
PATCH /conversations/{id} accepts {"read": true}, and GET /config has
conversationsTable when the session may query that table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the attachments package: uploads are read as the signed-in user's own
upload (core UploadRefs plus an owner check) into memory with byte caps;
the type is sniffed from content; executables, archives and unknown binary
data are refused; text and JSON are decoded with charset detection; PDF
page text comes from PDFBox (already on the classpath through core) with
page, character and memory caps and no font scan; CSV and XLSX previews
reuse core's bulk-load parsers; image sizes are read from headers.
Content is framed as an untrusted uploaded_file block with neutralized
delimiters. Limits live in AssistantQBitConfig.attachments.
Part of KofTwentyTwo/Website-Backend#305
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /assistant/config returned the profile's starter prompts as static
text, so a user could be offered examples about tables they cannot see.
profile.starterPrompts (same field and shape) is now built per user:
up to three prompts generated from the tables the user can read through
the assistant that have rows (list_tables, count_records and
describe_table via the UI API with the user's own session), cached five
minutes, stable for the day, bounded and fail-soft. Configured prompts
stay only when tagged with tables the user can read.
Part of KofTwentyTwo/Website-Backend#303
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The notification a task owner asked for (output mode Notification or Both)
now goes through core QAlerts.notify: category Job, the owner as the only
audience, severity by run status and a link to the conversation. It replaces
a reflective call into an older alerts SPI that no longer matched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A confirmed bulk load still launches a real durable job through
POST /qqq/v1/processes/{p}/jobs. Its tool result now carries jobHref (the
job's /app link) next to jobId and a record ref to the job, and the confirm
response's href points at the job, so the conversation links to it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ordinary chat turns no longer create core tracking jobs, so they stay out
of the Jobs tray and tables and no longer trigger a per-answer "finished"
notification. Crash safety comes from the assistant's own turn table
(leased, heartbeated assistant_turn rows, seq-numbered event replay and the
abandoned-turn sweep), which is unchanged.
Removes AssistantRunTracker, JobTrackingRunTracker, the config accessors and
the tracking id on RunningTurn, with their tests. The panel's Stop
(POST /turns/{id}/cancel) is unchanged and still covered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An enabled provider that is not the default and not the only route for any
configured routing (enabled profile simple/complex model, budget downgrade,
knowledge source embedding, with no fallback on another usable provider) is
optional. When it is unreachable its provider and model checks now report
DEGRADED with a message naming where requests go, instead of turning the
whole "assistant" component DOWN (central health rolls up worst-of; WARNING
severity does not cap DOWN). The default provider and sole routes stay DOWN.
Failed provider probes carry reachable=false so the circuit breaker still
refuses the provider when its central outcome is only DEGRADED.
New assistant_provider.setup_state (Active / Setting up, empty = Active):
a provider that is Setting up is never routed to (default, profile models,
fallbacks, budget downgrades, embeddings) and gets no provider or model
health checks. Additive guarded DDL in docs/schema-postgres.sql; see
UPGRADE.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Assistant health tile showed the HealthStatus name (UP/DEGRADED/DOWN/UNKNOWN). It now shows Healthy / Degraded / Down, and "Not checked yet" when no
check has reported, with the check cadence in the context line. The drill to health_check is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UI API extension assistant 1.5.0 adds POST /qqq/v1/assistant/client-errors
(AssistantClientErrorReportV1 in, AssistantClientErrorResponseV1 out, 202).
Any signed-in user may report; scope and message are required (400
otherwise, also for a non-object body). Every field is bounded, message and
stacks are scrubbed (AiRedactor secrets, e-mails, digit runs over 6, mixed
tokens, query strings), the route keeps only its path, and conversation /
message / turn ids are kept only when they are the user's own. Over
clientErrorsPerUserPerMinute (default 30) the report is acknowledged with
accepted:false and dropped, never a 429.
Rows go to the new owner-locked assistant_client_error table (Assistant app
nav, record screens, bundle help, channel wall by pattern, SET NULL foreign
keys in the reference DDL) and are deleted by retention after
toolResultRetentionDays. The assistant.client-errors health check is
DEGRADED at clientErrorWarnPerHour (default 20) reports in the last hour, so
the Assistant health card shows it too. The deprecated AssistantErrorV1
description again says "since 1.3.0".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- toolCallTimeoutSeconds (default 60): each tool call is bounded from when
it gets a permit, and never outlives the turn's deadline; a timed-out call
gets an ERROR is_error result.
- Tool exceptions (also Errors and toolbox failures) become an ERROR tool
part plus an error notice; the details go only to the log.
- The engine checks renders and presentations (RenderShapes) before it
emits or stores them; an undisplayable one is replaced by an error notice.
- Terminal events are emitted independently, so message.end and the
terminal turn row are always written.
- Conversation detail repairs messages left STREAMING (reaping orphaned
runs), and retention finalizes runs abandoned past the hard stream limit.
The recovery writes are shared in AbandonedTurns.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RenderShapes now checks all render types (records, record, count, widget,
history, pending_action, bulk_load_dry_run) and presentation blocks (table,
chart, metrics, filterLinks, recordLinks, actions): required lists are always
present, non-object entries are dropped and required strings get safe
defaults. A render that cannot be repaired is dropped and replaced by an
error notice ("This result could not be displayed."); unknown part and
render types pass through. Stored parts and replayed events are normalized
on read, so older rows are repaired too. Problems are logged with the type
and a fixed problem code only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A query that matched nothing produced a records render without rows or
columns: QQQ's JSON omits empty lists, and Next crashed reading
rows.length. Parts and stream events are now written keeping empty lists
(RenderShapes), stored ones are completed when read, and extension 1.4.0
documents AssistantRecordsRenderV1.
Streamed deltas arrive on the provider's virtual thread without a QContext,
so the writing-phase progress (JobLogWriter) failed with an NPE; the delta
handler now runs in the turn's captured context.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
QRun-IO/.github#2 adds a tag-and-release job that signs vX with the
QRUN_TAG_SIGNING_KEY secret after Maven Central confirms the artifact.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every AssistantRuntime registered a JVM shutdown hook that held the
runtime, and so its whole QInstance, until JVM exit. A host test suite
that builds an instance per test leaked every instance (kof22's suite ran
out of heap). The hook now holds a weak reference.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every operation has an operationId and the standard error responses
(BasicErrorResponseV1, keeping the assistant-specific codes); AssistantErrorV1
is kept but deprecated; bodyless 204 responses no longer reference null.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On release branches the bundle's version and the producer's differed, so the
bundle test that asserts they match failed, and released bundles recorded
SNAPSHOT as their provenance. help/*.yaml is now filtered:
version: ${project.version}.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>