The same fixtures work for both Gemini AI Studio and Vertex AI endpoints. See the
- Vertex AI page for configuration details.
+ Vertex AI page for configuration details.
diff --git a/docs/index.html b/docs/index.html
index e4fc411..4531500 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1068,7 +1068,7 @@
Replay
- Learn about Record & Replay →
+ Learn about Record & Replay →
@@ -1722,7 +1720,7 @@ Built for production
Home
- Docs
+ Docs
diff --git a/docs/metrics.html b/docs/metrics/index.html
similarity index 99%
rename from docs/metrics.html
rename to docs/metrics/index.html
index ae51423..d5e16c0 100644
--- a/docs/metrics.html
+++ b/docs/metrics/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/docs/migrate-from-mock-llm.html b/docs/migrate-from-mock-llm/index.html
similarity index 99%
rename from docs/migrate-from-mock-llm.html
rename to docs/migrate-from-mock-llm/index.html
index fd58940..743bfc2 100644
--- a/docs/migrate-from-mock-llm.html
+++ b/docs/migrate-from-mock-llm/index.html
@@ -123,7 +123,7 @@
Home
- Docs
+ Docs
@@ -469,7 +469,7 @@ Kubernetes migration
If you were using mock-llm's ConfigMap for inline responses, convert each response to a
fixture JSON file and load them via a PVC. See the
- Fixtures documentation for the full schema.
+ Fixtures documentation for the full schema.
diff --git a/docs/migrate-from-mokksy.html b/docs/migrate-from-mokksy/index.html
similarity index 99%
rename from docs/migrate-from-mokksy.html
rename to docs/migrate-from-mokksy/index.html
index 1a62258..05d4439 100644
--- a/docs/migrate-from-mokksy.html
+++ b/docs/migrate-from-mokksy/index.html
@@ -108,7 +108,7 @@
Home
- Docs
+ Docs
diff --git a/docs/migrate-from-msw.html b/docs/migrate-from-msw/index.html
similarity index 99%
rename from docs/migrate-from-msw.html
rename to docs/migrate-from-msw/index.html
index d61ecb2..f02fd3c 100644
--- a/docs/migrate-from-msw.html
+++ b/docs/migrate-from-msw/index.html
@@ -124,7 +124,7 @@
Home
- Docs
+ Docs
diff --git a/docs/migrate-from-piyook.html b/docs/migrate-from-piyook/index.html
similarity index 99%
rename from docs/migrate-from-piyook.html
rename to docs/migrate-from-piyook/index.html
index aaffc5b..9dd293c 100644
--- a/docs/migrate-from-piyook.html
+++ b/docs/migrate-from-piyook/index.html
@@ -123,7 +123,7 @@
Home
- Docs
+ Docs
diff --git a/docs/migrate-from-python-mocks.html b/docs/migrate-from-python-mocks/index.html
similarity index 99%
rename from docs/migrate-from-python-mocks.html
rename to docs/migrate-from-python-mocks/index.html
index ca93cda..70a62d6 100644
--- a/docs/migrate-from-python-mocks.html
+++ b/docs/migrate-from-python-mocks/index.html
@@ -124,7 +124,7 @@
Home
- Docs
+ Docs
diff --git a/docs/migrate-from-vidaimock.html b/docs/migrate-from-vidaimock/index.html
similarity index 99%
rename from docs/migrate-from-vidaimock.html
rename to docs/migrate-from-vidaimock/index.html
index b5f201f..421fe06 100644
--- a/docs/migrate-from-vidaimock.html
+++ b/docs/migrate-from-vidaimock/index.html
@@ -32,7 +32,7 @@
Home
- Docs
+ Docs
diff --git a/docs/mount.html b/docs/mount/index.html
similarity index 95%
rename from docs/mount.html
rename to docs/mount/index.html
index a069912..85d3ccc 100644
--- a/docs/mount.html
+++ b/docs/mount/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
@@ -227,21 +227,21 @@ Built-in Services
- MCPMock — Mock MCP tool server with
+ MCPMock — Mock MCP tool server with
JSON-RPC dispatch, session management, and tool/resource/prompt support
- A2AMock — Mock A2A agent-to-agent
+ A2AMock — Mock A2A agent-to-agent
protocol server with agent cards, message routing, and streaming
- VectorMock — Mock vector database
- with Pinecone, Qdrant, and ChromaDB endpoints
+ VectorMock — Mock vector database with
+ Pinecone, Qdrant, and ChromaDB endpoints
All implement the Mountable interface and work with mount(),
- createMockSuite(), and the aimock CLI .
+ createMockSuite(), and the aimock CLI .
diff --git a/docs/ollama.html b/docs/ollama/index.html
similarity index 99%
rename from docs/ollama.html
rename to docs/ollama/index.html
index c054ba3..f6999f0 100644
--- a/docs/ollama.html
+++ b/docs/ollama/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/docs/record-replay.html b/docs/record-replay/index.html
similarity index 99%
rename from docs/record-replay.html
rename to docs/record-replay/index.html
index 29c4a83..2fe22c2 100644
--- a/docs/record-replay.html
+++ b/docs/record-replay/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/docs/responses-api.html b/docs/responses-api/index.html
similarity index 98%
rename from docs/responses-api.html
rename to docs/responses-api/index.html
index a005ee8..f3e518b 100644
--- a/docs/responses-api.html
+++ b/docs/responses-api/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
@@ -158,7 +158,7 @@ SSE Event Sequence
The same fixtures work for both HTTP SSE and WebSocket transports. See the
- WebSocket APIs page for WebSocket-specific details.
+ WebSocket APIs page for WebSocket-specific details.
diff --git a/docs/sequential-responses.html b/docs/sequential-responses/index.html
similarity index 99%
rename from docs/sequential-responses.html
rename to docs/sequential-responses/index.html
index 517180b..bbb8b9c 100644
--- a/docs/sequential-responses.html
+++ b/docs/sequential-responses/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/docs/services.html b/docs/services/index.html
similarity index 99%
rename from docs/services.html
rename to docs/services/index.html
index 1d9e3e2..4f69628 100644
--- a/docs/services.html
+++ b/docs/services/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/docs/sidebar.js b/docs/sidebar.js
index 2af1d7d..90414b9 100644
--- a/docs/sidebar.js
+++ b/docs/sidebar.js
@@ -5,90 +5,90 @@
{
title: "Getting Started",
links: [
- { label: "Overview", href: "docs.html" },
- { label: "Record & Replay", href: "record-replay.html" },
- { label: "Quick Start: LLM", href: "chat-completions.html" },
- { label: "Quick Start: aimock", href: "aimock-cli.html" },
+ { label: "Overview", href: "/docs" },
+ { label: "Record & Replay", href: "/record-replay" },
+ { label: "Quick Start: LLM", href: "/chat-completions" },
+ { label: "Quick Start: aimock", href: "/aimock-cli" },
],
},
{
title: "LLM Providers",
links: [
- { label: "Chat Completions (OpenAI)", href: "chat-completions.html" },
- { label: "Responses API (OpenAI)", href: "responses-api.html" },
- { label: "Claude Messages", href: "claude-messages.html" },
- { label: "Gemini", href: "gemini.html" },
- { label: "Azure OpenAI", href: "azure-openai.html" },
- { label: "AWS Bedrock", href: "aws-bedrock.html" },
- { label: "Ollama", href: "ollama.html" },
- { label: "Cohere", href: "cohere.html" },
- { label: "Vertex AI", href: "vertex-ai.html" },
- { label: "Compatible Providers", href: "compatible-providers.html" },
+ { label: "Chat Completions (OpenAI)", href: "/chat-completions" },
+ { label: "Responses API (OpenAI)", href: "/responses-api" },
+ { label: "Claude Messages", href: "/claude-messages" },
+ { label: "Gemini", href: "/gemini" },
+ { label: "Azure OpenAI", href: "/azure-openai" },
+ { label: "AWS Bedrock", href: "/aws-bedrock" },
+ { label: "Ollama", href: "/ollama" },
+ { label: "Cohere", href: "/cohere" },
+ { label: "Vertex AI", href: "/vertex-ai" },
+ { label: "Compatible Providers", href: "/compatible-providers" },
],
},
{
title: "LLM Features",
links: [
- { label: "Embeddings", href: "embeddings.html" },
- { label: "Structured Output", href: "structured-output.html" },
- { label: "Sequential Responses", href: "sequential-responses.html" },
- { label: "Fixtures", href: "fixtures.html" },
- { label: "Error Injection", href: "error-injection.html" },
- { label: "Chaos Testing", href: "chaos-testing.html" },
- { label: "Streaming Physics", href: "streaming-physics.html" },
- { label: "WebSocket APIs", href: "websocket.html" },
- { label: "Prometheus Metrics", href: "metrics.html" },
- { label: "Mount & Composition", href: "mount.html" },
+ { label: "Embeddings", href: "/embeddings" },
+ { label: "Structured Output", href: "/structured-output" },
+ { label: "Sequential Responses", href: "/sequential-responses" },
+ { label: "Fixtures", href: "/fixtures" },
+ { label: "Error Injection", href: "/error-injection" },
+ { label: "Chaos Testing", href: "/chaos-testing" },
+ { label: "Streaming Physics", href: "/streaming-physics" },
+ { label: "WebSocket APIs", href: "/websocket" },
+ { label: "Prometheus Metrics", href: "/metrics" },
+ { label: "Mount & Composition", href: "/mount" },
],
},
{
title: "Additional Mocks",
links: [
- { label: "MCPMock", href: "mcp-mock.html" },
- { label: "A2AMock", href: "a2a-mock.html" },
- { label: "VectorMock", href: "vector-mock.html" },
- { label: "Services", href: "services.html" },
+ { label: "MCPMock", href: "/mcp-mock" },
+ { label: "A2AMock", href: "/a2a-mock" },
+ { label: "VectorMock", href: "/vector-mock" },
+ { label: "Services", href: "/services" },
],
},
{
title: "Orchestration",
links: [
- { label: "aimock CLI & Config", href: "aimock-cli.html" },
- { label: "Docker & Helm", href: "docker.html" },
- { label: "Drift Detection", href: "drift-detection.html" },
+ { label: "aimock CLI & Config", href: "/aimock-cli" },
+ { label: "Docker & Helm", href: "/docker" },
+ { label: "Drift Detection", href: "/drift-detection" },
],
},
{
title: "Switching to aimock",
links: [
- { label: "From MSW", href: "migrate-from-msw.html" },
- { label: "From VidaiMock", href: "migrate-from-vidaimock.html" },
- { label: "From mock-llm", href: "migrate-from-mock-llm.html" },
- { label: "From piyook/llm-mock", href: "migrate-from-piyook.html" },
- { label: "From Python Mocks", href: "migrate-from-python-mocks.html" },
- { label: "From Mokksy", href: "migrate-from-mokksy.html" },
+ { label: "From MSW", href: "/migrate-from-msw" },
+ { label: "From VidaiMock", href: "/migrate-from-vidaimock" },
+ { label: "From mock-llm", href: "/migrate-from-mock-llm" },
+ { label: "From piyook/llm-mock", href: "/migrate-from-piyook" },
+ { label: "From Python Mocks", href: "/migrate-from-python-mocks" },
+ { label: "From Mokksy", href: "/migrate-from-mokksy" },
],
},
];
// ─── Section Bar Items ──────────────────────────────────────────
var sectionBarItems = [
- { icon: "📡", label: "LLM Mocking", color: "pill-green", href: "chat-completions.html" },
- { icon: "🔌", label: "MCP Protocol", color: "pill-blue", href: "mcp-mock.html" },
- { icon: "🤝", label: "A2A Protocol", color: "pill-purple", href: "a2a-mock.html" },
- { icon: "📦", label: "Vector DBs", color: "pill-amber", href: "vector-mock.html" },
- { icon: "🔍", label: "Search & Rerank", color: "pill-red", href: "services.html" },
+ { icon: "📡", label: "LLM Mocking", color: "pill-green", href: "/chat-completions" },
+ { icon: "🔌", label: "MCP Protocol", color: "pill-blue", href: "/mcp-mock" },
+ { icon: "🤝", label: "A2A Protocol", color: "pill-purple", href: "/a2a-mock" },
+ { icon: "📦", label: "Vector DBs", color: "pill-amber", href: "/vector-mock" },
+ { icon: "🔍", label: "Search & Rerank", color: "pill-red", href: "/services" },
{
icon: "⚙",
label: "Chaos & DevOps",
color: "pill-gray",
- href: "chaos-testing.html",
+ href: "/chaos-testing",
},
];
// ─── Detect current page ────────────────────────────────────────
- var currentPage = window.location.pathname.split("/").pop() || "index.html";
- if (currentPage === "" || currentPage === "/") currentPage = "index.html";
+ var p = window.location.pathname.replace(/\/index\.html$/, "").replace(/\/$/, "");
+ var currentPage = p || "/";
// ─── Build Sidebar HTML ─────────────────────────────────────────
function buildSidebar() {
diff --git a/docs/streaming-physics.html b/docs/streaming-physics/index.html
similarity index 99%
rename from docs/streaming-physics.html
rename to docs/streaming-physics/index.html
index d39ec56..2793f5c 100644
--- a/docs/streaming-physics.html
+++ b/docs/streaming-physics/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/docs/structured-output.html b/docs/structured-output/index.html
similarity index 99%
rename from docs/structured-output.html
rename to docs/structured-output/index.html
index 35e89bb..e4307ee 100644
--- a/docs/structured-output.html
+++ b/docs/structured-output/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/docs/vector-mock.html b/docs/vector-mock/index.html
similarity index 99%
rename from docs/vector-mock.html
rename to docs/vector-mock/index.html
index cdbfe3e..c529e83 100644
--- a/docs/vector-mock.html
+++ b/docs/vector-mock/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/docs/vertex-ai.html b/docs/vertex-ai/index.html
similarity index 97%
rename from docs/vertex-ai.html
rename to docs/vertex-ai/index.html
index 5e13e0e..f6bcc68 100644
--- a/docs/vertex-ai.html
+++ b/docs/vertex-ai/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
@@ -133,8 +133,8 @@ Same Wire Format as Gemini
Vertex AI uses the exact same request and response wire format as the consumer Gemini API.
The request body uses contents with parts, and responses use
candidates with content.parts. See the
- Gemini documentation for full details on the wire format,
- streaming events, and fixture examples.
+ Gemini documentation for full details on the wire format, streaming
+ events, and fixture examples.
Internally, both consumer Gemini and Vertex AI routes are handled by the same
diff --git a/docs/websocket.html b/docs/websocket/index.html
similarity index 99%
rename from docs/websocket.html
rename to docs/websocket/index.html
index 0d9c074..81131b3 100644
--- a/docs/websocket.html
+++ b/docs/websocket/index.html
@@ -28,7 +28,7 @@
Home
- Docs
+ Docs
diff --git a/src/__tests__/docs-clean-urls.test.ts b/src/__tests__/docs-clean-urls.test.ts
new file mode 100644
index 0000000..1010064
--- /dev/null
+++ b/src/__tests__/docs-clean-urls.test.ts
@@ -0,0 +1,166 @@
+import { describe, it, expect } from "vitest";
+import fs from "node:fs";
+import path from "node:path";
+
+// ---------------------------------------------------------------------------
+// Helpers
+// ---------------------------------------------------------------------------
+
+const DOCS_DIR = path.resolve(import.meta.dirname, "../../docs");
+
+/** Recursively collect all HTML files under a directory. */
+function collectHtmlFiles(dir: string): string[] {
+ const results: string[] = [];
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
+ const full = path.join(dir, entry.name);
+ if (entry.isDirectory()) {
+ results.push(...collectHtmlFiles(full));
+ } else if (entry.name.endsWith(".html")) {
+ results.push(full);
+ }
+ }
+ return results;
+}
+
+/** Extract all href values from an HTML string (excludes external links and anchors). */
+function extractInternalHrefs(html: string): string[] {
+ const hrefRegex = /href="([^"]+)"/g;
+ const hrefs: string[] = [];
+ let match;
+ while ((match = hrefRegex.exec(html)) !== null) {
+ const href = match[1];
+ // Skip external links, anchors, and protocol-relative URLs
+ if (href.startsWith("http") || href.startsWith("#") || href.startsWith("//")) continue;
+ hrefs.push(href);
+ }
+ return hrefs;
+}
+
+const allHtmlFiles = collectHtmlFiles(DOCS_DIR);
+const SKIP_FILES = ["index.html", "og-image.html"];
+
+// ---------------------------------------------------------------------------
+// Tests
+// ---------------------------------------------------------------------------
+
+describe("docs clean URLs", () => {
+ it("docs directory exists and contains HTML files", () => {
+ expect(fs.existsSync(DOCS_DIR)).toBe(true);
+ expect(allHtmlFiles.length).toBeGreaterThan(0);
+ });
+
+ describe("file structure", () => {
+ it("only index.html and og-image.html exist at root level", () => {
+ const rootHtmlFiles = fs
+ .readdirSync(DOCS_DIR, { withFileTypes: true })
+ .filter((e) => e.isFile() && e.name.endsWith(".html"))
+ .map((e) => e.name);
+
+ for (const file of rootHtmlFiles) {
+ expect(SKIP_FILES).toContain(file);
+ }
+ });
+
+ it("each doc page lives in its own directory as index.html", () => {
+ // Non-page directories (specs, assets, etc.) are excluded
+ const NON_PAGE_DIRS = new Set(["superpowers"]);
+ const subdirs = fs
+ .readdirSync(DOCS_DIR, { withFileTypes: true })
+ .filter((e) => e.isDirectory() && !e.name.startsWith(".") && !NON_PAGE_DIRS.has(e.name));
+
+ expect(subdirs.length).toBeGreaterThan(0);
+
+ for (const dir of subdirs) {
+ const indexPath = path.join(DOCS_DIR, dir.name, "index.html");
+ expect(fs.existsSync(indexPath), `${dir.name}/index.html should exist`).toBe(true);
+ }
+ });
+
+ it("no stale .html files remain at the docs root (besides allowed ones)", () => {
+ const rootHtmlFiles = fs
+ .readdirSync(DOCS_DIR, { withFileTypes: true })
+ .filter((e) => e.isFile() && e.name.endsWith(".html"))
+ .map((e) => e.name);
+
+ const unexpected = rootHtmlFiles.filter((f) => !SKIP_FILES.includes(f));
+ expect(unexpected, `Unexpected root-level HTML files: ${unexpected.join(", ")}`).toEqual([]);
+ });
+ });
+
+ describe("internal links have no .html extension", () => {
+ for (const filePath of allHtmlFiles) {
+ const relative = path.relative(DOCS_DIR, filePath);
+
+ it(`${relative} — no .html in internal hrefs`, () => {
+ const html = fs.readFileSync(filePath, "utf-8");
+ const hrefs = extractInternalHrefs(html);
+
+ const badHrefs = hrefs.filter((h) => /\.html/.test(h));
+ expect(badHrefs, `Found .html hrefs in ${relative}: ${badHrefs.join(", ")}`).toEqual([]);
+ });
+ }
+ });
+
+ describe("sidebar.js links have no .html extension", () => {
+ it("no .html in sidebar href values", () => {
+ const sidebarPath = path.join(DOCS_DIR, "sidebar.js");
+ const content = fs.readFileSync(sidebarPath, "utf-8");
+
+ // Extract all href: "..." values
+ const hrefRegex = /href:\s*"([^"]+)"/g;
+ const hrefs: string[] = [];
+ let match;
+ while ((match = hrefRegex.exec(content)) !== null) {
+ hrefs.push(match[1]);
+ }
+
+ const badHrefs = hrefs.filter((h) => /\.html/.test(h));
+ expect(badHrefs, `Found .html hrefs in sidebar.js: ${badHrefs.join(", ")}`).toEqual([]);
+ });
+ });
+
+ describe("homepage replaceState redirect exists", () => {
+ it("index.html contains history.replaceState for /index.html cleanup", () => {
+ const indexPath = path.join(DOCS_DIR, "index.html");
+ const html = fs.readFileSync(indexPath, "utf-8");
+
+ expect(html).toContain("replaceState");
+ expect(html).toContain("index.html");
+ });
+ });
+
+ describe("all internal link targets resolve to existing pages", () => {
+ const knownPages = new Set();
+
+ // Build set of known page slugs from directory names
+ const subdirs = fs
+ .readdirSync(DOCS_DIR, { withFileTypes: true })
+ .filter((e) => e.isDirectory() && !e.name.startsWith("."))
+ .map((e) => e.name);
+
+ for (const dir of subdirs) {
+ knownPages.add(`/${dir}`);
+ }
+
+ for (const filePath of allHtmlFiles) {
+ const relative = path.relative(DOCS_DIR, filePath);
+
+ it(`${relative} — all internal links point to existing pages`, () => {
+ const html = fs.readFileSync(filePath, "utf-8");
+ const hrefs = extractInternalHrefs(html);
+
+ for (const href of hrefs) {
+ // Strip anchor
+ const base = href.split("#")[0];
+ if (base === "" || base === "/") continue; // root or anchor-only
+ if (base.startsWith("/")) {
+ expect(
+ knownPages.has(base),
+ `${relative} links to ${href} but no page directory exists for "${base}"`,
+ ).toBe(true);
+ }
+ }
+ });
+ }
+ });
+});
From d1914968ffe158401264f8c2b7984fc440178139 Mon Sep 17 00:00:00 2001
From: Jordan Ritter
Date: Wed, 8 Apr 2026 16:26:07 -0700
Subject: [PATCH 2/2] chore: release v1.9.0
Bump npm package to 1.9.0, aimock-pytest to 0.3.0, Helm appVersion,
and plugin/marketplace versions.
---
.claude-plugin/marketplace.json | 2 +-
.claude-plugin/plugin.json | 2 +-
CHANGELOG.md | 18 ++++++++++++++++++
charts/aimock/Chart.yaml | 2 +-
package.json | 2 +-
packages/aimock-pytest/pyproject.toml | 2 +-
6 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json
index 853f92f..2e71ec8 100644
--- a/.claude-plugin/marketplace.json
+++ b/.claude-plugin/marketplace.json
@@ -9,7 +9,7 @@
"source": {
"source": "npm",
"package": "@copilotkit/aimock",
- "version": "^1.8.0"
+ "version": "^1.9.0"
},
"description": "Fixture authoring skill for @copilotkit/aimock — match fields, response types, embeddings, structured output, sequential responses, streaming physics, agent loop patterns, gotchas, and debugging"
}
diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json
index 715f1e5..727c190 100644
--- a/.claude-plugin/plugin.json
+++ b/.claude-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "llmock",
- "version": "1.8.0",
+ "version": "1.9.0",
"description": "Fixture authoring guidance for @copilotkit/aimock",
"author": {
"name": "CopilotKit"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 035999f..bd911c7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# @copilotkit/aimock
+## 1.9.0
+
+### Minor Changes
+
+- Per-test sequence isolation via `X-Test-Id` header — each test gets its own fixture match counters, wired through all 12 HTTP handlers and 3 WebSocket handlers. No more test pollution from shared sequential state (#93)
+- Combined `content + toolCalls` in fixture responses — new `ContentWithToolCallsResponse` type and type guard, supported across OpenAI Chat, OpenAI Responses, Anthropic Messages, and Gemini, with stream collapse support (#92)
+- OpenRouter `reasoning_content` support in chat completions (#88)
+
+### Patch Changes
+
+- Fix `web_search_call` items to use `action.query` matching real OpenAI API format (#89)
+- Clean up homepage URL (remove `/index.html` suffix) (#90)
+- Center Record & Replay section title and top-align terminal panel (#87)
+- Add demo video to README (#91)
+- CI: Slack notifications for drift tests, competitive matrix updates, and new PRs (#86)
+- CI: use `pull_request_target` for fork PR Slack alerts
+- Docs: add reasoning and webSearches to Response Types table
+
## 1.8.0
### Minor Changes
diff --git a/charts/aimock/Chart.yaml b/charts/aimock/Chart.yaml
index b03377d..af314a3 100644
--- a/charts/aimock/Chart.yaml
+++ b/charts/aimock/Chart.yaml
@@ -3,4 +3,4 @@ name: aimock
description: Mock infrastructure for AI application testing (OpenAI, Anthropic, Gemini, MCP, A2A, vector)
type: application
version: 0.1.0
-appVersion: "1.8.0"
+appVersion: "1.9.0"
diff --git a/package.json b/package.json
index 147f19f..0ec1146 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@copilotkit/aimock",
- "version": "1.8.0",
+ "version": "1.9.0",
"description": "Mock infrastructure for AI application testing — LLM APIs, MCP tools, A2A agents, vector databases, search, and more. Zero dependencies.",
"license": "MIT",
"repository": {
diff --git a/packages/aimock-pytest/pyproject.toml b/packages/aimock-pytest/pyproject.toml
index cf6a57f..f83b519 100644
--- a/packages/aimock-pytest/pyproject.toml
+++ b/packages/aimock-pytest/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "aimock-pytest"
-version = "0.2.0"
+version = "0.3.0"
description = "pytest fixtures for aimock — mock LLM APIs, MCP, A2A, vector DBs"
readme = "README.md"
requires-python = ">=3.10"