@kanzo-tech/llm 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # @kanzo-tech/llm
2
+
3
+ The model conversation, without React.
4
+
5
+ ```bash
6
+ npm install @kanzo-tech/llm ai
7
+ ```
8
+
9
+ `ai` is a **required** peer, not an optional one: there is nothing here without it, and a host
10
+ installs it once so that its own agent and `@kanzo-tech/ai`'s components share one `UIMessage`, one
11
+ `ToolLoopAgent` and one transport. Same standing `@uwdata/mosaic-*` have in `@kanzo-tech/mosaic`.
12
+
13
+ ## What it holds
14
+
15
+ ```ts
16
+ import { createKanzo } from "@kanzo-tech/llm";
17
+ import { ToolLoopAgent, DirectChatTransport, tool, Output, streamText } from "@kanzo-tech/llm";
18
+ ```
19
+
20
+ - **`createKanzo({ baseURL })`** — the one door to a model. `kanzo("kanzo-chat")` is a model by
21
+ **alias**: which upstream answers it is the gateway's configuration, so a host's code is the same
22
+ in development (a local model) and in production. The gateway speaks OpenAI chat completions; its
23
+ key belongs to a server, so `baseURL` is normally the host's own authenticated proxy — keasy's is
24
+ `/api/v1/ai` — and a relative one is resolved against the page. Two things a host would otherwise
25
+ repeat happen here: a model that reasons inline in `<think>…</think>` (Hermes, DeepSeek, Qwen)
26
+ gets that lifted into the SDK's `reasoning` part, and structured output is on, so `Output.array`
27
+ asks the gateway for a JSON schema rather than prose to parse.
28
+ - **Re-exports** of the AI SDK surface a host needs — the agent, the transport, `tool`, `Output`,
29
+ `streamText`, and the message and part types — so a host never imports `ai` itself.
30
+ `@ai-sdk/openai-compatible` is not among them: `createKanzo` is the only way to a model.
31
+
32
+ ## Why it is not part of `@kanzo-tech/ai`
33
+
34
+ Reaching a model is not a user-interface concern, and not every caller draws one: a host's agent,
35
+ a server route or a test needs the model and none of the components. `@kanzo-tech/ai` depends on
36
+ this package and not the other way round.
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The model conversation, as one import.
3
+ *
4
+ * Same standing as `@kanzo-tech/mosaic`: the third party — here the AI SDK — is a required peer, its
5
+ * surface is re-exported so a host never imports `ai` itself, and what is ours is the one door it
6
+ * does not have. A host reaches a model only through `createKanzo`, an agent through
7
+ * `ToolLoopAgent`, and a conversation through `@kanzo-tech/ai`'s `useChat`, so one copy of the SDK
8
+ * is the easy outcome.
9
+ */
10
+ export { DirectChatTransport, Output, ToolLoopAgent, getToolName, isToolUIPart, jsonSchema, stepCountIs, streamText, tool, type ChatStatus, type DynamicToolUIPart, type InferAgentUIMessage, type LanguageModel, type ReasoningUIPart, type ToolUIPart, type UIMessage, } from "ai";
11
+ /** Ours: the one door to a model. */
12
+ export { createKanzo, type Kanzo, type KanzoSettings } from "./kanzo.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,mBAAmB,EACnB,MAAM,EACN,aAAa,EACb,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,IAAI,EACJ,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,SAAS,GACf,MAAM,IAAI,CAAC;AAEZ,qCAAqC;AACrC,OAAO,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The model conversation, as one import.
3
+ *
4
+ * Same standing as `@kanzo-tech/mosaic`: the third party — here the AI SDK — is a required peer, its
5
+ * surface is re-exported so a host never imports `ai` itself, and what is ours is the one door it
6
+ * does not have. A host reaches a model only through `createKanzo`, an agent through
7
+ * `ToolLoopAgent`, and a conversation through `@kanzo-tech/ai`'s `useChat`, so one copy of the SDK
8
+ * is the easy outcome.
9
+ */
10
+ export { DirectChatTransport, Output, ToolLoopAgent, getToolName, isToolUIPart, jsonSchema, stepCountIs, streamText, tool, } from "ai";
11
+ /** Ours: the one door to a model. */
12
+ export { createKanzo } from "./kanzo.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,mBAAmB,EACnB,MAAM,EACN,aAAa,EACb,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,UAAU,EACV,IAAI,GAQL,MAAM,IAAI,CAAC;AAEZ,qCAAqC;AACrC,OAAO,EAAE,WAAW,EAAkC,MAAM,YAAY,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { type LanguageModel } from "ai";
2
+ export interface KanzoSettings {
3
+ /**
4
+ * Where the gateway's OpenAI-compatible API is, as the browser reaches it. Behind a BFF that is
5
+ * the host's own proxy — keasy's is `/api/v1/ai` — because the key that opens the gateway must
6
+ * never be in the page.
7
+ */
8
+ baseURL: string;
9
+ /** Sent with every request; the place for a CSRF header a BFF asks for. */
10
+ headers?: Record<string, string>;
11
+ /** The request function, for a host that routes through its own client. */
12
+ fetch?: typeof globalThis.fetch;
13
+ }
14
+ /** A model behind the gateway, by alias. */
15
+ export type Kanzo = (alias: string) => LanguageModel;
16
+ /**
17
+ * The one door to a model: name an **alias** (`kanzo-chat`, `kanzo-complete`), never a provider.
18
+ * Which upstream answers it is the gateway's configuration, so a host's code is the same in dev,
19
+ * where a local model answers, and in prod.
20
+ *
21
+ * Two things a host would otherwise repeat are done here, once:
22
+ *
23
+ * - **A model that reasons in tags gets its reasoning back as reasoning.** Open-weight models
24
+ * (Hermes, DeepSeek, Qwen) write it inline as `<think>…</think>` because the chat completions
25
+ * protocol has no field for it; the middleware lifts it into the SDK's `reasoning` part, which is
26
+ * what `Chat` draws as reasoning. A model that never writes the tag is untouched.
27
+ * - **Structured output is on**, so `Output.object`/`Output.array` ask the gateway for a JSON
28
+ * schema rather than prose the caller would parse — the "return ONLY JSON, no fences" prompt and
29
+ * its fence-stripping is what this ends.
30
+ */
31
+ export declare function createKanzo(settings: KanzoSettings): Kanzo;
32
+ //# sourceMappingURL=kanzo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanzo.d.ts","sourceRoot":"","sources":["../src/kanzo.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,KAAK,aAAa,EAAqB,MAAM,IAAI,CAAC;AAEvF,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED,4CAA4C;AAC5C,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,aAAa,CAAC;AAErD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,KAAK,CAW1D"}
package/dist/kanzo.js ADDED
@@ -0,0 +1,39 @@
1
+ import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
2
+ import { extractReasoningMiddleware, wrapLanguageModel } from "ai";
3
+ /**
4
+ * The one door to a model: name an **alias** (`kanzo-chat`, `kanzo-complete`), never a provider.
5
+ * Which upstream answers it is the gateway's configuration, so a host's code is the same in dev,
6
+ * where a local model answers, and in prod.
7
+ *
8
+ * Two things a host would otherwise repeat are done here, once:
9
+ *
10
+ * - **A model that reasons in tags gets its reasoning back as reasoning.** Open-weight models
11
+ * (Hermes, DeepSeek, Qwen) write it inline as `<think>…</think>` because the chat completions
12
+ * protocol has no field for it; the middleware lifts it into the SDK's `reasoning` part, which is
13
+ * what `Chat` draws as reasoning. A model that never writes the tag is untouched.
14
+ * - **Structured output is on**, so `Output.object`/`Output.array` ask the gateway for a JSON
15
+ * schema rather than prose the caller would parse — the "return ONLY JSON, no fences" prompt and
16
+ * its fence-stripping is what this ends.
17
+ */
18
+ export function createKanzo(settings) {
19
+ const provider = createOpenAICompatible({
20
+ name: "kanzo",
21
+ baseURL: absolute(settings.baseURL),
22
+ headers: settings.headers,
23
+ fetch: settings.fetch,
24
+ includeUsage: true,
25
+ supportsStructuredOutputs: true,
26
+ });
27
+ const reasoning = extractReasoningMiddleware({ tagName: "think" });
28
+ return (alias) => wrapLanguageModel({ model: provider(alias), middleware: reasoning });
29
+ }
30
+ /**
31
+ * The provider builds `new URL(baseURL + path)` with no base, so the BFF's own path — the one a
32
+ * host is told to pass — would throw `Invalid URL` in the browser too. Resolved against the page,
33
+ * once, here.
34
+ */
35
+ function absolute(baseURL) {
36
+ const page = globalThis.location?.href;
37
+ return page ? new URL(baseURL, page).toString().replace(/\/$/, "") : baseURL;
38
+ }
39
+ //# sourceMappingURL=kanzo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanzo.js","sourceRoot":"","sources":["../src/kanzo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAsB,iBAAiB,EAAE,MAAM,IAAI,CAAC;AAkBvF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW,CAAC,QAAuB;IACjD,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACtC,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;QACnC,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,YAAY,EAAE,IAAI;QAClB,yBAAyB,EAAE,IAAI;KAChC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,0BAA0B,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;AACzF,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAAC,OAAe;IAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC/E,CAAC"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@kanzo-tech/llm",
3
+ "version": "0.17.0",
4
+ "description": "The model conversation, without React — the AI SDK re-exported as one surface, plus `createKanzo`, the one door to models behind a Kanzo AI gateway.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "//dependencies": "@ai-sdk/openai-compatible is a dependency, not a peer: it is how `createKanzo` speaks to the gateway, and nothing outside this package names it — the same standing @duckdb/duckdb-wasm has in @kanzo-tech/mosaic, behind `engine()`.",
22
+ "//peers": "`ai` is REQUIRED, not optional, and that is the point of this package: there is nothing here without it, and a host installs it once so @kanzo-tech/ai's components and the host's own agent see the same UIMessage, the same ToolLoopAgent and the same transport. Two copies would be two type universes that do not assign to each other.",
23
+ "dependencies": {
24
+ "@ai-sdk/openai-compatible": "^3.0.62"
25
+ },
26
+ "peerDependencies": {
27
+ "ai": "^7.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "ai": "^7.0.126"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/Kanzo-Tech/ui.git",
35
+ "directory": "packages/llm"
36
+ },
37
+ "homepage": "https://kanzo-tech.github.io/ui",
38
+ "bugs": {
39
+ "url": "https://github.com/Kanzo-Tech/ui/issues"
40
+ },
41
+ "scripts": {
42
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
43
+ "typecheck": "tsc --noEmit",
44
+ "test": "vitest run"
45
+ }
46
+ }