@vezham/tamizhi-core 0.0.0-stage → 26.3.2

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/LICENSE ADDED
@@ -0,0 +1,173 @@
1
+ SPDX-License-Identifier: BUSL-1.1
2
+
3
+ Business Source License 1.1
4
+
5
+ License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
6
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
7
+
8
+ ---
9
+
10
+ Parameters
11
+
12
+ Licensor: Vezham Technologies Private Limited
13
+
14
+ Licensed Work: The source code and packages in this repository (“the Licensed Work”).
15
+ The Licensed Work is (c) 2025–present Vezham Technologies Private Limited
16
+
17
+ Release Tag: The applicable release tag or commit identifier (for example, “v1.0.0”)
18
+ published by the Licensor for this version of the Licensed Work.
19
+ Users must cross-check the tag or commit identifier to verify
20
+ the release version and applicable Change Date.
21
+
22
+ Additional Use Grant: 1. You may make non-production use of the Licensed Work.
23
+
24
+ 2. You may make production use of the Licensed Work, provided
25
+ your use does not include offering the Licensed Work, or any
26
+ derivative thereof, to third parties on a hosted, embedded,
27
+ or managed basis in order to compete with the Licensor’s
28
+ commercial offerings based on the Licensed Work, or offerings
29
+ that provide substantially similar functionality.
30
+
31
+ For purposes of this license:
32
+
33
+ A “competitive offering” is a Product that is offered to third
34
+ parties on a paid basis, including through paid support,
35
+ consulting, managed service arrangements, or similar commercial
36
+ relationships, that significantly overlaps with the capabilities
37
+ or functionality of the Licensor’s commercial offerings based on
38
+ the Licensed Work.
39
+
40
+ If your Product is not a competitive offering when you first
41
+ make it generally available, it will not become a competitive
42
+ offering solely because the Licensor releases a new version of the
43
+ Licensed Work with additional features or capabilities. Products
44
+ that are not provided on a paid basis are not competitive offerings.
45
+
46
+ “Product” means any software or service that is (a) offered to end
47
+ users for deployment in their own environments (self-managed), or
48
+ (b) offered as a hosted, cloud, or managed service by you or on
49
+ your behalf.
50
+
51
+ “Embedded” means including the source code or executable code of
52
+ the Licensed Work in a competitive offering. “Embedded” also means
53
+ packaging or distributing the competitive offering in a way that
54
+ requires the Licensed Work to be accessed, invoked, or downloaded
55
+ for the competitive offering to function.
56
+
57
+ Hosting or using the Licensed Work internally within your own
58
+ organization, including your affiliates under common control,
59
+ is not considered a competitive offering.
60
+
61
+ 3. Educational institutions and legally recognised non-profit
62
+ organizations may use the Licensed Work in a production
63
+ environment without restriction, provided such use is not
64
+ for commercial profit.
65
+
66
+ For binding interpretive guidance on using Vezham products under
67
+ the Business Source License, please visit our licensing FAQ:
68
+ https://trust.vezham.com/legal/license-faq
69
+
70
+ Change Date: Four (4) years from the date the Licensed Work is first publicly
71
+ released under the specified Release Tag
72
+
73
+ Change License: GNU Affero General Public License v3.0 (AGPL-3.0-or-later)
74
+ The full text of the Change License is available at:
75
+ https://www.gnu.org/licenses/agpl-3.0.html
76
+
77
+ For information about commercial licensing or alternative arrangements,
78
+ please contact the Licensor at: https://vezham.com
79
+ or email: license@vezham.com
80
+
81
+ For formal legal notices or IP-related correspondence,
82
+ please contact: licensor@vezham.com
83
+
84
+ ---
85
+
86
+ Notice
87
+
88
+ The Business Source License (this document, or the "License") is not an Open
89
+ Source license. However, the Licensed Work will eventually be made available
90
+ under an Open Source License, as stated in this License.
91
+
92
+ For more information on the use of the Business Source License generally,
93
+ please visit the Adopting and Developing Business Source License FAQ at:
94
+ https://mariadb.com/bsl-faq-adopting
95
+
96
+ ---
97
+
98
+ Business Source License 1.1
99
+
100
+ ---
101
+
102
+ Terms
103
+
104
+ The Licensor hereby grants you the right to copy, modify, create derivative
105
+ works, redistribute, and make non-production use of the Licensed Work.
106
+ The Licensor may make an Additional Use Grant, above, permitting limited
107
+ production use.
108
+
109
+ Effective on the Change Date, or the fourth anniversary of the first publicly
110
+ available distribution of a specific version of the Licensed Work under this
111
+ License, whichever comes first, the Licensor hereby grants you rights under
112
+ the terms of the Change License, and the rights granted in the paragraph
113
+ above terminate.
114
+
115
+ If your use of the Licensed Work does not comply with the requirements
116
+ currently in effect as described in this License, you must purchase a
117
+ commercial license from the Licensor, its affiliated entities, or authorized
118
+ resellers, or you must refrain from using the Licensed Work.
119
+
120
+ All copies of the original and modified Licensed Work, and derivative works
121
+ of the Licensed Work, are subject to this License. This License applies
122
+ separately for each version of the Licensed Work, and the Change Date may
123
+ vary for each version of the Licensed Work released by the Licensor.
124
+
125
+ You must conspicuously display this License on each original or modified copy
126
+ of the Licensed Work. If you receive the Licensed Work in original or modified
127
+ form from a third party, the terms and conditions set forth in this License
128
+ apply to your use of that work.
129
+
130
+ Any use of the Licensed Work in violation of this License will automatically
131
+ terminate your rights under this License for the current and all other versions
132
+ of the Licensed Work.
133
+
134
+ This License does not grant you any right in any trademark or logo of the
135
+ Licensor or its affiliates (provided that you may use a trademark or logo of
136
+ the Licensor as expressly required by this License).
137
+
138
+ ---
139
+
140
+ Disclaimer
141
+
142
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
143
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
144
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
145
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
146
+ TITLE.
147
+
148
+ -----------------------------------------------------------------------------
149
+
150
+ MariaDB hereby grants you permission to use this License’s text to license your
151
+ works, and to refer to it using the trademark "Business Source License", as long
152
+ as you comply with the Covenants of Licensor below.
153
+
154
+ Covenants of Licensor
155
+
156
+ In consideration of the right to use this License’s text and the "Business
157
+ Source License" name and trademark, Licensor covenants to MariaDB, and to all
158
+ other recipients of the licensed work to be provided by Licensor:
159
+
160
+ 1. To specify as the Change License the GPL Version 3.0 or any later version,
161
+ or a license that is compatible with GPL Version 3.0 or a later version,
162
+ where "compatible" means that software provided under the Change License can
163
+ be included in a program with software provided under GPL Version 3.0 or a
164
+ later version. Licensor may specify additional Change Licenses without
165
+ limitation.
166
+
167
+ 2. To either: (a) specify an additional grant of rights to use that does not
168
+ impose any additional restriction on the right granted in this License, as
169
+ the Additional Use Grant; or (b) insert the text "None".
170
+
171
+ 3. To specify a Change Date.
172
+
173
+ 4. Not to modify this License in any other way.
package/README.md CHANGED
@@ -1,3 +1,7 @@
1
- # Temporary Holding Version
1
+ # TypeScript runtime prototype
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ This package preserves the earlier Cordis/TanStack AI implementation and its comparison tests. The production Tamizhi backend is now Go in the sibling `vx-be-kit-lab` workspace. Static frontend applications use `@vezham/tamizhi-client` and must not import this package.
4
+
5
+ See [the Tamizhi package guide](../README.md) for the current integration.
6
+
7
+ Local example data defaults to `.vezham/tamizhi/data`, relative to the working directory. Set `TAMIZHI_DATA_DIRECTORY` to override it.
@@ -0,0 +1,6 @@
1
+ export * from './lib/types';
2
+ export * from './lib/runtime';
3
+ export * from './lib/plugins';
4
+ export * from './lib/http';
5
+ export * from './lib/tanstack-provider';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,yBAAyB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ import { createTamizhi } from "./lib/runtime.js";
2
+ import { memoryStoragePlugin, permissionPolicyPlugin, toolPlugin } from "./lib/plugins.js";
3
+ import { httpTransportPlugin } from "./lib/http.js";
4
+ import { openaiCompatiblePlugin, tanstackProviderPlugin } from "./lib/tanstack-provider.js";
5
+ export { createTamizhi, httpTransportPlugin, memoryStoragePlugin, openaiCompatiblePlugin, permissionPolicyPlugin, tanstackProviderPlugin, toolPlugin };
@@ -0,0 +1,9 @@
1
+ import { Principal, TamizhiPlugin } from './types';
2
+ export interface HttpTransportOptions {
3
+ authenticate: (request: Request) => Principal | null | Promise<Principal | null>;
4
+ allowedOrigins?: string[];
5
+ basePath?: string;
6
+ maxBodyBytes?: number;
7
+ }
8
+ export declare const httpTransportPlugin: (options: HttpTransportOptions) => TamizhiPlugin;
9
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAEvD,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,CACZ,OAAO,EAAE,OAAO,KACb,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;IACjD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AA4BD,eAAO,MAAM,mBAAmB,GAC9B,SAAS,oBAAoB,KAC5B,aAuHD,CAAA"}
@@ -0,0 +1,120 @@
1
+ import { createLinkedAbortController } from "./linked-abort.js";
2
+ import { approvalDecisionSchema, runRequestSchema } from "@vezham/tamizhi-contracts";
3
+ //#region src/lib/http.ts
4
+ var readJson = async (request, maximum) => {
5
+ const reader = request.body?.getReader();
6
+ if (!reader) throw new Error("A JSON body is required");
7
+ const decoder = new TextDecoder();
8
+ let size = 0;
9
+ let text = "";
10
+ try {
11
+ for (;;) {
12
+ const { done, value } = await reader.read();
13
+ if (done) break;
14
+ size += value.byteLength;
15
+ if (size > maximum) {
16
+ await reader.cancel();
17
+ throw new Error("Request is too large");
18
+ }
19
+ text += decoder.decode(value, { stream: true });
20
+ }
21
+ return JSON.parse(text + decoder.decode());
22
+ } finally {
23
+ reader.releaseLock();
24
+ }
25
+ };
26
+ var httpTransportPlugin = (options) => ({
27
+ name: "transport.http",
28
+ inject: ["tamizhi"],
29
+ apply: (context) => {
30
+ const base = (options.basePath ?? "/api/tamizhi").replace(/\/$/, "");
31
+ const handler = async (request) => {
32
+ const origin = request.headers.get("origin");
33
+ const headers = new Headers({
34
+ "Cache-Control": "no-store",
35
+ Vary: "Origin"
36
+ });
37
+ const localOrigin = new URL(request.url).origin;
38
+ if (origin && origin !== localOrigin && !options.allowedOrigins?.includes(origin)) return new Response("Origin is not allowed", { status: 403 });
39
+ if (origin) {
40
+ headers.set("Access-Control-Allow-Origin", origin);
41
+ headers.set("Access-Control-Allow-Credentials", "true");
42
+ }
43
+ const json = (value, status = 200) => Response.json(value, {
44
+ status,
45
+ headers
46
+ });
47
+ if (request.method === "OPTIONS") {
48
+ headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
49
+ headers.set("Access-Control-Allow-Headers", "Authorization, Content-Type");
50
+ return new Response(null, {
51
+ status: 204,
52
+ headers
53
+ });
54
+ }
55
+ const principal = await options.authenticate(request);
56
+ if (!principal?.id) return json({ error: "Authentication is required" }, 401);
57
+ const path = new URL(request.url).pathname;
58
+ const host = context.tamizhi.host;
59
+ if (request.method === "GET" && path === `${base}/models`) return json(host.models());
60
+ if (request.method === "GET" && path === `${base}/plugins`) return json(host.plugins());
61
+ if (request.method === "GET" && path.startsWith(`${base}/conversations/`)) {
62
+ let id;
63
+ try {
64
+ id = decodeURIComponent(path.slice(`${base}/conversations/`.length));
65
+ } catch {
66
+ return json({ error: "Invalid conversation id" }, 400);
67
+ }
68
+ if (!id || id.length > 128) return json({ error: "Invalid conversation id" }, 400);
69
+ const conversation = await host.conversation(principal, id);
70
+ return conversation ? json(conversation) : json({ error: "Conversation not found" }, 404);
71
+ }
72
+ if (request.method !== "POST") return json({ error: "Route not found" }, 404);
73
+ if (path !== `${base}/chat` && path !== `${base}/approvals`) return json({ error: "Route not found" }, 404);
74
+ try {
75
+ const body = await readJson(request, options.maxBodyBytes ?? 256e3);
76
+ if (path === `${base}/approvals`) {
77
+ const decision = approvalDecisionSchema.parse(body);
78
+ const accepted = host.approve(principal, decision.runId, decision.callId, decision.approved);
79
+ return json({ accepted }, accepted ? 200 : 404);
80
+ }
81
+ const input = runRequestSchema.parse(body);
82
+ const { controller, abort, cleanup } = createLinkedAbortController(request.signal);
83
+ const iterator = host.run(input, principal, controller.signal)[Symbol.asyncIterator]();
84
+ let pending = await iterator.next();
85
+ const encoder = new TextEncoder();
86
+ const stream = new ReadableStream({
87
+ async pull(output) {
88
+ try {
89
+ const next = pending;
90
+ if (next.done) {
91
+ output.close();
92
+ cleanup();
93
+ return;
94
+ }
95
+ output.enqueue(encoder.encode(`data: ${JSON.stringify(next.value)}\n\n`));
96
+ pending = await iterator.next();
97
+ } catch (error) {
98
+ output.error(error);
99
+ abort();
100
+ cleanup();
101
+ }
102
+ },
103
+ async cancel() {
104
+ abort();
105
+ cleanup();
106
+ await iterator.return?.();
107
+ }
108
+ });
109
+ headers.set("Content-Type", "text/event-stream; charset=utf-8");
110
+ headers.set("X-Accel-Buffering", "no");
111
+ return new Response(stream, { headers });
112
+ } catch {
113
+ return json({ error: "Invalid or conflicting chat request" }, 400);
114
+ }
115
+ };
116
+ context.tamizhi.transports.register(context, "http", handler);
117
+ }
118
+ });
119
+ //#endregion
120
+ export { httpTransportPlugin };
@@ -0,0 +1,6 @@
1
+ export declare const createLinkedAbortController: (signal: AbortSignal) => {
2
+ controller: AbortController;
3
+ abort: () => void;
4
+ cleanup: () => void;
5
+ };
6
+ //# sourceMappingURL=linked-abort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linked-abort.d.ts","sourceRoot":"","sources":["../../src/lib/linked-abort.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,GAAI,QAAQ,WAAW;;;;CAO9D,CAAA"}
@@ -0,0 +1,15 @@
1
+ //#region src/lib/linked-abort.ts
2
+ var createLinkedAbortController = (signal) => {
3
+ const controller = new AbortController();
4
+ const abort = () => controller.abort();
5
+ signal.addEventListener("abort", abort, { once: true });
6
+ if (signal.aborted) abort();
7
+ const cleanup = () => signal.removeEventListener("abort", abort);
8
+ return {
9
+ controller,
10
+ abort,
11
+ cleanup
12
+ };
13
+ };
14
+ //#endregion
15
+ export { createLinkedAbortController };
@@ -0,0 +1,5 @@
1
+ import { createTamizhi } from './runtime';
2
+ import { TamizhiPlugin } from './types';
3
+ export declare const fileStoragePlugin: (directory: string) => TamizhiPlugin;
4
+ export declare const createTamizhiServer: (runtime: Pick<Awaited<ReturnType<typeof createTamizhi>>, "fetch">) => import('node:http').Server<typeof import('node:http').IncomingMessage, typeof import('node:http').ServerResponse>;
5
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/lib/node.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,KAAG,aA8CpD,CAAA;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,sHAmE/D,CAAA"}
@@ -0,0 +1,98 @@
1
+ import { storedConversationSchema, wireMessageSchema } from "@vezham/tamizhi-contracts";
2
+ import { createHash, randomUUID } from "node:crypto";
3
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
4
+ import { createServer } from "node:http";
5
+ import { join } from "node:path";
6
+ import { Readable } from "node:stream";
7
+ //#region src/lib/node.ts
8
+ var fileStoragePlugin = (directory) => ({
9
+ name: "storage.file",
10
+ inject: ["tamizhi"],
11
+ apply: (context) => {
12
+ const filename = (owner, id) => join(directory, `${createHash("sha256").update(JSON.stringify([owner, id])).digest("hex")}.json`);
13
+ context.tamizhi.storage.register(context, "default", {
14
+ get: async (owner, id) => {
15
+ try {
16
+ const item = storedConversationSchema.parse(JSON.parse(await readFile(filename(owner, id), "utf8")));
17
+ return {
18
+ ...item,
19
+ messages: item.messages.map((message) => wireMessageSchema.parse(message))
20
+ };
21
+ } catch (error) {
22
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return void 0;
23
+ throw error;
24
+ }
25
+ },
26
+ put: async (owner, conversation) => {
27
+ await mkdir(directory, {
28
+ recursive: true,
29
+ mode: 448
30
+ });
31
+ const target = filename(owner, conversation.id);
32
+ const temporary = `${target}.${randomUUID()}.tmp`;
33
+ await writeFile(temporary, JSON.stringify(storedConversationSchema.parse(conversation)), { mode: 384 });
34
+ await rename(temporary, target);
35
+ }
36
+ });
37
+ }
38
+ });
39
+ var createTamizhiServer = (runtime) => createServer(async (incoming, outgoing) => {
40
+ const controller = new AbortController();
41
+ outgoing.on("close", () => {
42
+ if (!outgoing.writableEnded) controller.abort();
43
+ });
44
+ try {
45
+ const headers = new Headers();
46
+ for (const [key, value] of Object.entries(incoming.headers)) if (Array.isArray(value)) for (const part of value) headers.append(key, part);
47
+ else if (value) headers.set(key, value);
48
+ const init = {
49
+ method: incoming.method,
50
+ headers,
51
+ signal: controller.signal
52
+ };
53
+ if (incoming.method !== "GET" && incoming.method !== "HEAD") {
54
+ init.body = Readable.toWeb(incoming);
55
+ init.duplex = "half";
56
+ }
57
+ const request = new Request(`http://localhost${incoming.url ?? "/"}`, init);
58
+ const response = await runtime.fetch(request);
59
+ outgoing.writeHead(response.status, Object.fromEntries(response.headers));
60
+ if (!response.body) {
61
+ outgoing.end();
62
+ return;
63
+ }
64
+ const reader = response.body.getReader();
65
+ try {
66
+ for (;;) {
67
+ controller.signal.throwIfAborted();
68
+ const { done, value } = await reader.read();
69
+ if (done) break;
70
+ if (!outgoing.write(value)) await new Promise((resolve, reject) => {
71
+ const clean = () => {
72
+ outgoing.off("drain", drained);
73
+ outgoing.off("close", closed);
74
+ };
75
+ const drained = () => {
76
+ clean();
77
+ resolve();
78
+ };
79
+ const closed = () => {
80
+ clean();
81
+ reject(/* @__PURE__ */ new Error("Connection closed"));
82
+ };
83
+ outgoing.once("drain", drained);
84
+ outgoing.once("close", closed);
85
+ });
86
+ }
87
+ outgoing.end();
88
+ } finally {
89
+ await reader.cancel().catch(() => void 0);
90
+ reader.releaseLock();
91
+ }
92
+ } catch {
93
+ if (!outgoing.headersSent) outgoing.writeHead(500, { "Content-Type": "application/json" });
94
+ outgoing.end(JSON.stringify({ error: "Tamizhi request failed" }));
95
+ }
96
+ });
97
+ //#endregion
98
+ export { createTamizhiServer, fileStoragePlugin };
@@ -0,0 +1,7 @@
1
+ import { TamizhiPlugin, Tool } from './types';
2
+ export declare const memoryStoragePlugin: () => TamizhiPlugin;
3
+ export declare const permissionPolicyPlugin: (options?: {
4
+ allowFullAccess?: boolean;
5
+ }) => TamizhiPlugin;
6
+ export declare const toolPlugin: (tool: Tool) => TamizhiPlugin;
7
+ //# sourceMappingURL=plugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/lib/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,aAAa,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE7E,eAAO,MAAM,mBAAmB,QAAO,aAgCtC,CAAA;AAED,eAAO,MAAM,sBAAsB,GACjC,UAAS;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,KAC1C,aAaD,CAAA;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,KAAG,aAItC,CAAA"}
@@ -0,0 +1,48 @@
1
+ //#region src/lib/plugins.ts
2
+ var memoryStoragePlugin = () => {
3
+ const owners = /* @__PURE__ */ new Map();
4
+ return {
5
+ name: "storage.memory",
6
+ inject: ["tamizhi"],
7
+ apply: (context) => {
8
+ context.tamizhi.storage.register(context, "default", {
9
+ get: async (owner, id) => {
10
+ const value = owners.get(owner)?.get(id);
11
+ return value ? structuredClone(value) : void 0;
12
+ },
13
+ put: async (owner, conversation) => {
14
+ let records = owners.get(owner);
15
+ if (!records) {
16
+ records = /* @__PURE__ */ new Map();
17
+ owners.set(owner, records);
18
+ }
19
+ records.delete(conversation.id);
20
+ records.set(conversation.id, structuredClone(conversation));
21
+ if (records.size > 100) {
22
+ const oldest = records.keys().next().value;
23
+ if (oldest) records.delete(oldest);
24
+ }
25
+ }
26
+ });
27
+ context.effect(() => () => owners.clear());
28
+ }
29
+ };
30
+ };
31
+ var permissionPolicyPlugin = (options = {}) => ({
32
+ name: "permissions.default",
33
+ inject: ["tamizhi"],
34
+ apply: (context) => {
35
+ context.tamizhi.permissions.register(context, "default", { evaluate: (mode, tool) => {
36
+ if (mode === "full" && options.allowFullAccess) return "allow";
37
+ if (mode === "safe" && tool.risk === "read") return "allow";
38
+ return "ask";
39
+ } });
40
+ }
41
+ });
42
+ var toolPlugin = (tool) => ({
43
+ name: `tool.${tool.name}`,
44
+ inject: ["tamizhi"],
45
+ apply: (context) => context.tamizhi.tools.register(context, tool.name, tool)
46
+ });
47
+ //#endregion
48
+ export { memoryStoragePlugin, permissionPolicyPlugin, toolPlugin };
@@ -0,0 +1,7 @@
1
+ export declare const createEventQueue: <T extends object>() => {
2
+ push: (value: T) => void;
3
+ fail: (error: Error) => void;
4
+ close: () => void;
5
+ stream: () => AsyncGenerator<T>;
6
+ };
7
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/lib/queue.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,MAAM;kBAM/B,CAAC;kBAMD,KAAK;;kBAUS,cAAc,CAAC,CAAC,CAAC;CAahD,CAAA"}
@@ -0,0 +1,38 @@
1
+ //#region src/lib/queue.ts
2
+ var createEventQueue = () => {
3
+ const values = [];
4
+ let wake;
5
+ let ended = false;
6
+ let failure;
7
+ return {
8
+ push: (value) => {
9
+ if (ended) return;
10
+ if (values.length >= 4096) throw new Error("Stream consumer is too slow");
11
+ values.push(value);
12
+ wake?.();
13
+ },
14
+ fail: (error) => {
15
+ failure = error;
16
+ ended = true;
17
+ values.length = 0;
18
+ wake?.();
19
+ },
20
+ close: () => {
21
+ ended = true;
22
+ wake?.();
23
+ },
24
+ stream: async function* () {
25
+ while (!ended || values.length || failure) {
26
+ if (failure) throw failure;
27
+ if (values.length) {
28
+ const value = values.shift();
29
+ if (value) yield value;
30
+ } else await new Promise((resolve) => {
31
+ wake = resolve;
32
+ });
33
+ }
34
+ }
35
+ };
36
+ };
37
+ //#endregion
38
+ export { createEventQueue };
@@ -0,0 +1,3 @@
1
+ import { Registry } from './types';
2
+ export declare const createRegistry: <T>(onRemove?: () => void) => Registry<T>;
3
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/lib/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,WAAW,MAAM,IAAI,KAAG,QAAQ,CAAC,CAAC,CAgBnE,CAAA"}
@@ -0,0 +1,20 @@
1
+ //#region src/lib/registry.ts
2
+ var createRegistry = (onRemove) => {
3
+ const values = /* @__PURE__ */ new Map();
4
+ return {
5
+ register: (context, id, value) => {
6
+ if (values.has(id)) throw new Error(`Duplicate registration: ${id}`);
7
+ context.effect(() => {
8
+ values.set(id, value);
9
+ return () => {
10
+ values.delete(id);
11
+ onRemove?.();
12
+ };
13
+ });
14
+ },
15
+ get: (id) => values.get(id),
16
+ entries: () => [...values.entries()]
17
+ };
18
+ };
19
+ //#endregion
20
+ export { createRegistry };
@@ -0,0 +1,22 @@
1
+ import { Context } from '@deepseek-ai/cordis';
2
+ import { StreamEvent } from '@vezham/tamizhi-contracts';
3
+ import { TamizhiPlugin } from './types';
4
+ export interface RuntimeOptions {
5
+ plugins: TamizhiPlugin[];
6
+ defaultModel?: string;
7
+ approvalTimeoutMs?: number;
8
+ runTimeoutMs?: number;
9
+ maxConcurrentRuns?: number;
10
+ }
11
+ export declare const createTamizhi: (options: RuntimeOptions) => Promise<{
12
+ context: Context;
13
+ mount: (plugin: TamizhiPlugin) => Promise<() => Promise<void>>;
14
+ fetch: (request: Request) => Promise<Response>;
15
+ dispose: () => Promise<void>;
16
+ run: (request: import('@vezham/tamizhi-contracts').RunRequest, principal: import('./types').Principal, signal?: AbortSignal) => AsyncIterable<StreamEvent>;
17
+ approve: (principal: import('./types').Principal, runId: string, callId: string, approved: boolean) => boolean;
18
+ conversation: (principal: import('./types').Principal, id: string) => Promise<import('./types').StoredConversation | undefined>;
19
+ models: () => import('@vezham/tamizhi-contracts').ModelInfo[];
20
+ plugins: () => string[];
21
+ }>;
22
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/lib/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAE7C,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAK7E,OAAO,KAAK,EAAkB,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,eAAO,MAAM,aAAa,GAAU,SAAS,cAAc;;oBAuN5B,aAAa;qBA2BvB,OAAO;;iHAzNQ,CAAC;;;;;EAwOpC,CAAA"}
@@ -0,0 +1,248 @@
1
+ import { createEventQueue } from "./queue.js";
2
+ import { createRegistry } from "./registry.js";
3
+ import { Context } from "@deepseek-ai/cordis";
4
+ import { runRequestSchema } from "@vezham/tamizhi-contracts";
5
+ //#region src/lib/runtime.ts
6
+ var createTamizhi = async (options) => {
7
+ const context = new Context();
8
+ const running = /* @__PURE__ */ new Map();
9
+ const approvals = /* @__PURE__ */ new Map();
10
+ let disposed = false;
11
+ const cancelAll = () => {
12
+ for (const run of running.values()) run.abort();
13
+ };
14
+ const plugins = /* @__PURE__ */ new Map();
15
+ const services = {
16
+ providers: createRegistry(cancelAll),
17
+ tools: createRegistry(cancelAll),
18
+ storage: createRegistry(cancelAll),
19
+ permissions: createRegistry(cancelAll),
20
+ transports: createRegistry()
21
+ };
22
+ const host = {
23
+ conversation: (principal, id) => services.storage.get("default")?.get(principal.id, id) ?? Promise.resolve(void 0),
24
+ models: () => services.providers.entries().flatMap(([, provider]) => provider.models),
25
+ plugins: () => [...plugins.keys()],
26
+ approve: (principal, runId, callId, approved) => {
27
+ const pending = approvals.get(`${runId}:${callId}`);
28
+ if (!pending || pending.owner !== principal.id) return false;
29
+ pending.decide(approved);
30
+ return true;
31
+ },
32
+ run: async function* (input, principal, externalSignal) {
33
+ if (disposed) throw new Error("Tamizhi runtime has been disposed");
34
+ const request = runRequestSchema.parse(input);
35
+ const key = JSON.stringify([principal.id, request.conversationId]);
36
+ if (running.has(key)) throw new Error("A reply is already running for this conversation");
37
+ if (running.size >= (options.maxConcurrentRuns ?? 32)) throw new Error("Tamizhi is busy");
38
+ const controller = new AbortController();
39
+ const abort = () => controller.abort();
40
+ externalSignal?.addEventListener("abort", abort, { once: true });
41
+ if (externalSignal?.aborted) controller.abort();
42
+ running.set(key, controller);
43
+ const timeout = setTimeout(abort, options.runTimeoutMs ?? 12e4);
44
+ const queue = createEventQueue();
45
+ const identity = {
46
+ runId: crypto.randomUUID(),
47
+ conversationId: request.conversationId
48
+ };
49
+ const emit = (event) => {
50
+ queue.push(event);
51
+ context.parallel("tamizhi/event", event, principal).catch(() => context.logger("tamizhi").warn("An event observer failed"));
52
+ };
53
+ const waitForApproval = (approval) => new Promise((resolve, reject) => {
54
+ const id = `${approval.runId}:${approval.callId}`;
55
+ let settled = false;
56
+ const finish = (approved) => {
57
+ if (settled) return;
58
+ settled = true;
59
+ clearTimeout(timer);
60
+ controller.signal.removeEventListener("abort", canceled);
61
+ approvals.delete(id);
62
+ resolve(approved);
63
+ };
64
+ const canceled = () => {
65
+ finish(false);
66
+ reject(/* @__PURE__ */ new Error("Run canceled"));
67
+ };
68
+ const timer = setTimeout(() => finish(false), options.approvalTimeoutMs ?? 6e4);
69
+ approvals.set(id, {
70
+ owner: principal.id,
71
+ decide: finish
72
+ });
73
+ controller.signal.addEventListener("abort", canceled, { once: true });
74
+ if (controller.signal.aborted) canceled();
75
+ else emit({
76
+ ...identity,
77
+ type: "approval",
78
+ ...approval
79
+ });
80
+ });
81
+ const produce = async () => {
82
+ emit({
83
+ ...identity,
84
+ type: "start"
85
+ });
86
+ try {
87
+ const model = request.model === "Auto" ? options.defaultModel : request.model ?? options.defaultModel;
88
+ const provider = services.providers.entries().find(([, item]) => !model || item.models.some((info) => info.id === model))?.[1];
89
+ if (!provider) throw new Error("No provider is configured for this model");
90
+ const storage = services.storage.get("default");
91
+ if (!storage) throw new Error("No conversation storage plugin is configured");
92
+ const policy = services.permissions.get("default");
93
+ if (!policy) throw new Error("No permission policy plugin is configured");
94
+ let text = "";
95
+ const executeTool = async (name, input, callId) => {
96
+ controller.signal.throwIfAborted();
97
+ const tool = services.tools.get(name);
98
+ if (!tool) throw new Error(`Unknown tool: ${name}`);
99
+ input = await tool.inputSchema.parseAsync(input);
100
+ emit({
101
+ ...identity,
102
+ type: "tool",
103
+ name,
104
+ input,
105
+ callId
106
+ });
107
+ const decision = policy.evaluate(request.permission, tool, principal);
108
+ if (decision === "deny" || decision === "ask" && !await waitForApproval({
109
+ runId: identity.runId,
110
+ callId,
111
+ name,
112
+ input
113
+ })) {
114
+ const output = { error: "Tool request was not approved" };
115
+ emit({
116
+ ...identity,
117
+ type: "tool-result",
118
+ name,
119
+ callId,
120
+ output
121
+ });
122
+ return output;
123
+ }
124
+ controller.signal.throwIfAborted();
125
+ const output = await tool.execute(input, {
126
+ principal,
127
+ conversationId: request.conversationId,
128
+ signal: controller.signal
129
+ });
130
+ emit({
131
+ ...identity,
132
+ type: "tool-result",
133
+ name,
134
+ callId,
135
+ output
136
+ });
137
+ return output;
138
+ };
139
+ await storage.put(principal.id, {
140
+ id: request.conversationId,
141
+ messages: request.messages,
142
+ updatedAt: Date.now()
143
+ });
144
+ try {
145
+ for await (const delta of provider.stream({
146
+ ...request,
147
+ model: model ?? provider.models[0]?.id,
148
+ signal: controller.signal,
149
+ tools: services.tools.entries().map(([, tool]) => tool),
150
+ executeTool
151
+ })) {
152
+ controller.signal.throwIfAborted();
153
+ if (text.length + delta.length > 1e5) throw new Error("Response is too large");
154
+ text += delta;
155
+ emit({
156
+ ...identity,
157
+ type: "text",
158
+ delta
159
+ });
160
+ }
161
+ } finally {
162
+ if (text) await storage.put(principal.id, {
163
+ id: request.conversationId,
164
+ messages: [...request.messages, {
165
+ role: "assistant",
166
+ content: text
167
+ }].slice(-60),
168
+ updatedAt: Date.now()
169
+ });
170
+ }
171
+ emit({
172
+ ...identity,
173
+ type: "finish",
174
+ reason: controller.signal.aborted ? "canceled" : "complete"
175
+ });
176
+ } catch (error) {
177
+ emit(controller.signal.aborted ? {
178
+ ...identity,
179
+ type: "finish",
180
+ reason: "canceled"
181
+ } : {
182
+ ...identity,
183
+ type: "error",
184
+ message: error instanceof Error && error.message.startsWith("No ") ? error.message : "The response could not be completed. Please retry."
185
+ });
186
+ } finally {
187
+ clearTimeout(timeout);
188
+ externalSignal?.removeEventListener("abort", abort);
189
+ running.delete(key);
190
+ queue.close();
191
+ }
192
+ };
193
+ const producer = produce().catch(() => {
194
+ controller.abort();
195
+ queue.fail(/* @__PURE__ */ new Error("The response stream could not be completed"));
196
+ });
197
+ try {
198
+ yield* queue.stream();
199
+ } finally {
200
+ controller.abort();
201
+ await producer;
202
+ }
203
+ }
204
+ };
205
+ const foundation = await context.plugin({
206
+ name: "tamizhi",
207
+ apply: (scope) => scope.provide("tamizhi", {
208
+ ...services,
209
+ host
210
+ })
211
+ });
212
+ const mount = async (plugin) => {
213
+ const name = plugin.name;
214
+ if (!name) throw new Error("Tamizhi plugins need a name");
215
+ if (disposed) throw new Error("Tamizhi runtime has been disposed");
216
+ if (plugins.has(name)) throw new Error(`Duplicate plugin: ${name}`);
217
+ const fiber = await foundation.ctx.plugin(plugin);
218
+ plugins.set(name, fiber);
219
+ return async () => {
220
+ cancelAll();
221
+ await fiber.dispose();
222
+ plugins.delete(name);
223
+ };
224
+ };
225
+ try {
226
+ await options.plugins.reduce((ready, plugin) => ready.then(() => mount(plugin)), Promise.resolve());
227
+ } catch (error) {
228
+ await foundation.dispose();
229
+ throw error;
230
+ }
231
+ return {
232
+ ...host,
233
+ context,
234
+ mount,
235
+ fetch: (request) => {
236
+ const handler = services.transports.get("http");
237
+ return handler ? handler(request) : Promise.resolve(new Response("HTTP transport is not installed", { status: 503 }));
238
+ },
239
+ dispose: async () => {
240
+ disposed = true;
241
+ cancelAll();
242
+ await foundation.dispose();
243
+ plugins.clear();
244
+ }
245
+ };
246
+ };
247
+ //#endregion
248
+ export { createTamizhi };
@@ -0,0 +1,22 @@
1
+ import { AnyTextAdapter } from '@tanstack/ai';
2
+ import { ModelInfo } from '@vezham/tamizhi-contracts';
3
+ import { TamizhiPlugin } from './types';
4
+ export interface TanStackProviderOptions {
5
+ id: string;
6
+ models: ModelInfo[];
7
+ adapter: (model: string, fast: boolean) => AnyTextAdapter;
8
+ systemPrompt?: string;
9
+ maxIterations?: number;
10
+ }
11
+ export declare const tanstackProviderPlugin: (options: TanStackProviderOptions) => TamizhiPlugin;
12
+ export interface OpenAICompatibleOptions {
13
+ id: string;
14
+ apiKey: string;
15
+ baseURL?: string;
16
+ models: ModelInfo[];
17
+ systemPrompt?: string;
18
+ fastModel?: string;
19
+ fetch?: typeof globalThis.fetch;
20
+ }
21
+ export declare const openaiCompatiblePlugin: (options: OpenAICompatibleOptions) => TamizhiPlugin;
22
+ //# sourceMappingURL=tanstack-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tanstack-provider.d.ts","sourceRoot":"","sources":["../../src/lib/tanstack-provider.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,cAAc,CAAA;IACzD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,sBAAsB,GACjC,SAAS,uBAAuB,KAC/B,aA8CD,CAAA;AAEF,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAChC;AAED,eAAO,MAAM,sBAAsB,GACjC,SAAS,uBAAuB,KAC/B,aAcC,CAAA"}
@@ -0,0 +1,50 @@
1
+ import { createLinkedAbortController } from "./linked-abort.js";
2
+ import { chat, createModel, extendAdapter, maxIterations, toolDefinition } from "@tanstack/ai";
3
+ import { createOpenaiChatCompletions } from "@tanstack/ai-openai";
4
+ //#region src/lib/tanstack-provider.ts
5
+ var tanstackProviderPlugin = (options) => ({
6
+ name: `provider.${options.id}`,
7
+ inject: ["tamizhi"],
8
+ apply: (context) => {
9
+ context.tamizhi.providers.register(context, options.id, {
10
+ models: options.models,
11
+ stream: async function* (request) {
12
+ const model = request.model ?? options.models[0]?.id;
13
+ if (!model) throw new Error("No model is configured");
14
+ const { controller, cleanup } = createLinkedAbortController(request.signal);
15
+ const tools = request.tools.map((tool) => toolDefinition({
16
+ name: tool.name,
17
+ description: tool.description,
18
+ inputSchema: tool.inputSchema
19
+ }).server((input, execution) => request.executeTool(tool.name, input, execution?.toolCallId ?? crypto.randomUUID())));
20
+ try {
21
+ for await (const event of chat({
22
+ adapter: options.adapter(model, request.fast),
23
+ messages: request.messages,
24
+ systemPrompts: [options.systemPrompt ?? "You are Tamizhi, a helpful assistant. Use tools only when needed."],
25
+ tools,
26
+ abortController: controller,
27
+ agentLoopStrategy: maxIterations(options.maxIterations ?? 8)
28
+ })) {
29
+ if (event.type === "TEXT_MESSAGE_CONTENT") yield event.delta;
30
+ if (event.type === "RUN_ERROR") throw new Error(event.message);
31
+ }
32
+ } finally {
33
+ cleanup();
34
+ }
35
+ }
36
+ });
37
+ }
38
+ });
39
+ var openaiCompatiblePlugin = (options) => tanstackProviderPlugin({
40
+ id: options.id,
41
+ models: options.models,
42
+ systemPrompt: options.systemPrompt,
43
+ adapter: (model, fast) => extendAdapter(createOpenaiChatCompletions, options.models.map((item) => createModel(item.id, ["text"])))(fast && options.fastModel ? options.fastModel : model, options.apiKey, {
44
+ baseURL: options.baseURL,
45
+ fetch: options.fetch,
46
+ maxRetries: 0
47
+ })
48
+ });
49
+ //#endregion
50
+ export { openaiCompatiblePlugin, tanstackProviderPlugin };
@@ -0,0 +1,69 @@
1
+ import { Context, Plugin } from '@deepseek-ai/cordis';
2
+ import { ZodType } from 'zod';
3
+ import { ModelInfo, PermissionMode, RunRequest, StreamEvent, WireMessage } from '@vezham/tamizhi-contracts';
4
+ export type TamizhiPlugin = Plugin.Object<void>;
5
+ export interface Registry<T> {
6
+ register: (context: Context, id: string, value: T) => void;
7
+ get: (id: string) => T | undefined;
8
+ entries: () => [string, T][];
9
+ }
10
+ export interface Principal {
11
+ id: string;
12
+ }
13
+ export interface ToolContext {
14
+ principal: Principal;
15
+ conversationId: string;
16
+ signal: AbortSignal;
17
+ }
18
+ export interface Tool {
19
+ name: string;
20
+ description: string;
21
+ risk: 'read' | 'write' | 'external';
22
+ inputSchema: ZodType;
23
+ execute: (input: unknown, context: ToolContext) => Promise<unknown>;
24
+ }
25
+ export interface ProviderRequest extends RunRequest {
26
+ signal: AbortSignal;
27
+ executeTool: (name: string, input: unknown, callId: string) => Promise<unknown>;
28
+ tools: Tool[];
29
+ }
30
+ export interface Provider {
31
+ models: ModelInfo[];
32
+ stream: (request: ProviderRequest) => AsyncIterable<string>;
33
+ }
34
+ export interface StoredConversation {
35
+ id: string;
36
+ messages: WireMessage[];
37
+ updatedAt: number;
38
+ }
39
+ export interface Storage {
40
+ get: (owner: string, id: string) => Promise<StoredConversation | undefined>;
41
+ put: (owner: string, conversation: StoredConversation) => Promise<void>;
42
+ }
43
+ export interface PermissionPolicy {
44
+ evaluate: (mode: PermissionMode, tool: Tool, principal: Principal) => 'allow' | 'ask' | 'deny';
45
+ }
46
+ export interface Host {
47
+ run: (request: RunRequest, principal: Principal, signal?: AbortSignal) => AsyncIterable<StreamEvent>;
48
+ approve: (principal: Principal, runId: string, callId: string, approved: boolean) => boolean;
49
+ conversation: (principal: Principal, id: string) => Promise<StoredConversation | undefined>;
50
+ models: () => ModelInfo[];
51
+ plugins: () => string[];
52
+ }
53
+ export interface TamizhiServices {
54
+ providers: Registry<Provider>;
55
+ tools: Registry<Tool>;
56
+ storage: Registry<Storage>;
57
+ permissions: Registry<PermissionPolicy>;
58
+ transports: Registry<(request: Request) => Promise<Response>>;
59
+ host: Host;
60
+ }
61
+ declare module '@deepseek-ai/cordis' {
62
+ interface Context {
63
+ tamizhi: TamizhiServices;
64
+ }
65
+ interface Events {
66
+ 'tamizhi/event': (event: StreamEvent, principal: Principal) => void;
67
+ }
68
+ }
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,43 @@
1
1
  {
2
2
  "name": "@vezham/tamizhi-core",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "26.3.2",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/vezham/vx-fe-pkgs.git",
7
+ "directory": "packages/tamizhi/core"
8
+ },
9
+ "type": "module",
10
+ "exports": {
11
+ ".": {
12
+ "@vx/fe-kit": "./src/index.ts",
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./package.json": "./package.json",
18
+ "./node": {
19
+ "@vx/fe-kit": "./src/lib/node.ts",
20
+ "types": "./dist/lib/node.d.ts",
21
+ "import": "./dist/lib/node.js",
22
+ "default": "./dist/lib/node.js"
23
+ }
24
+ },
25
+ "main": "./dist/index.js",
26
+ "module": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "files": [
29
+ "!**/*.tsbuildinfo",
30
+ "dist",
31
+ "LICENSE"
32
+ ],
33
+ "dependencies": {
34
+ "@deepseek-ai/cordis": "4.0.5",
35
+ "@tanstack/ai": "0.71.0",
36
+ "@tanstack/ai-openai": "0.31.0",
37
+ "@vezham/tamizhi-contracts": "26.3.2",
38
+ "zod": "^4.6.7"
39
+ },
40
+ "devDependencies": {
41
+ "@vezham/tamizhi-client": "26.3.2"
42
+ }
6
43
  }