Repository navigation
release: core 0.5.0, server 0.6.0, widget 0.6.0 with protocol v1, shared storage and endpoint protection - #320
Merged
Merged
Conversation
sync: production into dev
* Fixes #83 * Fixes #183 * Update README.md Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com> * Update packages/widget/README.md Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com> --------- Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
POST /api/visitors incremented the counter on every call. The EVAL script in incrementVisitors now runs SET <key> 1 NX EX 86400 first and only increments when it succeeds, so a visit still costs one Upstash command. The key is a SHA-256 hash of the cf-connecting-ip header and the UTC date; the raw IP is never stored. Without the header (local dev), every call still counts.
…le, add publint (#218)
A provider whose setup rejects (unknown provider.type, SDK that throws on a missing key) is now handled where it is created: logged once with the [chatcops] prefix, message only, so no API key or config is logged. Each chat request then gets provider_error instead of an unhandled rejection that stops the server process. Request validation and rate limiting run before the provider is awaited, as before. Closes #175 Co-authored-by: Saif Ullah jafri <saifullahjafri@Saifs-MacBook-Air.local> Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
) Types only, no behavior change. ChatMessage gains optional parts, status, usage and aiGenerated; Conversation gains an optional version. partsOf() and messageText() read parts from any message, including ones saved without them. ProviderEvent and an optional AIProvider.step() describe a single model request. WirePart, ChatRequestV1 and the error body describe protocol v1, which the widget will ask for with protocol: 1 in the body. Type-level tests (*.test-d.ts) now run through tsc in the core project.
* FIxed bot answer docs Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> * Update promt Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> * update promt Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> --------- Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
…uite (#243) ConversationStore gains optional append (atomic, versioned, ConflictError on a stale expectedVersion), updateMessage, removeMessage, list and purge. CounterStore, KeyValueStore and EventSink join it in ChatCopsStorage. memoryStorage() implements every capability in process with bounded maps and lazy expiry, so it needs no timers. withAppend() gives a 0.4 store the new conversation methods. @chatcops/core/testing exports runStorageConformance() for store packages and custom stores.
#244) vitest projects and publint now cover every packages/* folder, so a new store package needs no root changes. The test job starts Redis, the Upstash REST emulator and Postgres and exposes them as CHATCOPS_TEST_* variables for the conformance suite. Store packages get their own coverage minimum, peer dependents of core only bump when out of range, and CONTRIBUTING has a section on writing a store package.
…tartup (#250) ToolDefinition and ChatTool take an inputSchema (any JSON Schema with an object root). The flat 0.4 parameters form still works and is converted by toolInputSchema(). execute() gets a context with the conversation id and an AbortSignal. The server runs validateTools() when it starts, so an invalid or duplicate name or a bad schema fails at boot with every problem listed.
#251) ConversationManager takes a ChatCopsStorage, defaults to memoryStorage() and writes through append (wrapping 0.4 stores with withAppend and a one-time warning), so two instances on one conversation keep every message. A conversation is saved with its first message, not on first read. History for the model is trimmed by an estimated token budget, keeping the first user turn. New appendMessages, updateMessage, getHistory and acquireTurn. normalizeHistory moves to providers/history.
* Use randomId Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> * added changeset Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> * Address review Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> --------- Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com>
* feat(widget): mark assistant messages with data-ai-generated * docs(widget): explain reaching ai generated replies through the shadow root --------- Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
…context after them (#264)
* docs: add server storage guide * docs: address storage review feedback * docs: finalize storage retention section --------- Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
* perf(widget): drop xmlns from the inline icons The icons are set with innerHTML, and the HTML parser already puts <svg> in the SVG namespace, so the xmlns attribute does nothing. The same 36-character string was repeated in five icons (panel, fab, input). Script tag bundle: 13798 -> 13769 bytes gzipped (-29). * perf(widget): drop the default easing keyword and shorten the shadow token "ease" is the default transition timing function, so "0.2s ease" and "0.2s" give the same computed styles. Also write the --cc-shadow custom property compactly, since custom property values are kept as written. I tried the same for the spaces after ":" in the other custom properties, but theme.test.ts reads the stylesheet text and looks for "--cc-accent: ", so those stay as they are. Script tag bundle: 13769 -> 13761 bytes gzipped (-8). * chore: add a changeset for the widget bundle trim --------- Co-authored-by: Saif Ullah jafri <saifullahjafri@Saifs-MacBook-Air.local> Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
* feat: add SQLite storage package * fix: address SQLite store review feedback * style: format SQLite conversation store --------- Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
* test(e2e): cover cross-origin chat requests * test(e2e): fix cross-origin request assertion * test(e2e): address cross-origin review feedback --------- Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
…ider and provider imports (#308) Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
* docs(server): add protocol reference for custom clients * docs(server): address protocol reference review --------- Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
… Objects (#296) * feat(store-cloudflare): add Cloudflare storage for D1, KV and Durable Objects (#249) * fix(store-cloudflare): fix concurrency bottlenecks and increase vitest timeout * fix(store-cloudflare): address maintainer review feedback for PR #296 --------- Co-authored-by: Bhushan Agrawal <bhushanagrawal@Bhushans-MacBook-Air.local>
* feat(core): buffer analytics events into sinks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(core): document buffered analytics sinks --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
* docs: add scheduled purge recipes * docs(server): address purge scheduling review feedback --------- Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
Adds checkSecuritySettings() in packages/server/src/security/startup-checks.ts and tests. Reports errors/warnings for: - session secrets < 32 bytes (UTF-8) - secret matches NEXT_PUBLIC_, VITE_, PUBLIC_, NUXT_PUBLIC_, EXPO_PUBLIC_, REACT_APP_ env vars - allowed origin not http(s):// or * - origin with path/query/trailing slash - * combined with other origins - duplicate secrets (warn) - http:// origin not localhost/127.0.0.1 (warn) Not exported from @chatcops/server yet. Closes #231
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The P1 release: the new reply engine, protocol v1 on the wire, shared storage, and endpoint protection. This was planned as two releases (0.6 in December, 0.7 in January). All of it is on
devand ready, so it ships as one.Versions after the version PR:
@chatcops/core0.4.0 to 0.5.0,@chatcops/server0.5.0 to 0.6.0,@chatcops/widget0.5.0 to 0.6.0. The four store packages are stillprivateand don't publish here. Their first publish comes after this release. The version PR will try to bump them to 1.0.0, because they list core as a peer dependency and core moves from 0.4 to 0.5, so I'll set them to 0.1.0 in that PR before it's merged.What's in it
Core
runTurn()runs a reply: model steps, tool calls in parallel, abort, and saving the reply as it grows.step()on Claude, OpenAI and Gemini replaces their own tool loops, andchat()/chatSync()are now deprecated wrappers (feat(core): add Claude step() and replay recorded provider streams in tests #260-feat(core): run every reply through runTurn, with tools between model steps #263)inputSchema, and the server checks tool definitions at startup (feat(core): describe tool input with JSON Schema and check tools at startup #250)openai-compatibleprovider andregisterProvider()(feat(core): add compatible providers and custom registration #289). Provider SDKs load lazily, so the classes moved to@chatcops/core/providers/*(239-Unloading provider SDKs #288)memoryStorage()and a conformance suite (feat(core): add storage interfaces, memoryStorage and a conformance suite #243), plus budgets and a rate limiter onCounterStore(245-Added rate limiter #274, feat: add token, reply and dollar budgets checked before each model request #277), and buffered analytics into an event sink (feat(core): buffer analytics events into sinks #314)Server
storagefor shared conversations, limits and locks, withpurge()andretention(feat(server): add a storage option, retention and purge() #273). Budgets on by default (feat(server): turn budgets on by default #279)allowedOrigins(feat(server): add allowedOrigins and refuse other sites with 403 #281), trusted client IP per adapter (feat(server): read the visitor's IP only from headers the platform sets #280), session tokens withPOST /session(feat(server): add POST /session and session tokens on chat requests #301), Turnstile (feat(server): check Cloudflare Turnstile before issuing a session #303), a security log at startup (feat(server): log security settings and mistakes at startup #318)chatcopsAiSdkHandlerfor the AI SDK'suseChat(feat(server): add chatcopsAiSdkHandler for the AI SDK's useChat #287)Widget
Docs: upgrade guide, security page, protocol reference, storage page with scheduled purge, pre-chat form guide, providers page.
Upgrade notes
All of it is on the new "Upgrading from 0.5" page. The parts most likely to need action:
budgetsto change them.trust proxy) work as is. Other hosts needclientIp, or per-IP limits are skipped.@chatcops/core/providers/claude,/openaiand/gemini.createProvider()doesn't change.corsandconversationStoreare deprecated in favor ofallowedOriginsandstorage.How it was tested
On
devat 5b31899: build, typecheck, 1152 unit tests and 15 Chromium e2e tests pass. The e2e tests include the published 0.5.0 widget against this server. Live run with real Claude, OpenAI and Gemini keys, all 14 checks passed:temperaturewith one warning