@yak-io/trpc 0.1.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/LICENSE +36 -0
- package/README.md +103 -0
- package/dist/adapters.d.ts +63 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +63 -0
- package/dist/caller.d.ts +25 -0
- package/dist/caller.d.ts.map +1 -0
- package/dist/caller.js +181 -0
- package/dist/createNextChatbotConfigHandler.d.ts +47 -0
- package/dist/createNextChatbotConfigHandler.d.ts.map +1 -0
- package/dist/createNextChatbotConfigHandler.js +49 -0
- package/dist/createNextChatbotToolManifestHandler.d.ts +44 -0
- package/dist/createNextChatbotToolManifestHandler.d.ts.map +1 -0
- package/dist/createNextChatbotToolManifestHandler.js +36 -0
- package/dist/createNextChatbotToolsHandler.d.ts +50 -0
- package/dist/createNextChatbotToolsHandler.d.ts.map +1 -0
- package/dist/createNextChatbotToolsHandler.js +126 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/introspect.d.ts +44 -0
- package/dist/introspect.d.ts.map +1 -0
- package/dist/introspect.js +79 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +15 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Yak Proprietary License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Yak. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are the
|
|
6
|
+
proprietary property of Yak and are protected by copyright law.
|
|
7
|
+
|
|
8
|
+
GRANT OF LICENSE:
|
|
9
|
+
Subject to the terms of this license and your valid subscription or agreement
|
|
10
|
+
with Yak, you are granted a limited, non-exclusive, non-transferable license
|
|
11
|
+
to use the Software solely for integrating the Yak chatbot widget into your
|
|
12
|
+
applications as intended and documented.
|
|
13
|
+
|
|
14
|
+
RESTRICTIONS:
|
|
15
|
+
You may NOT:
|
|
16
|
+
- Modify, adapt, alter, translate, or create derivative works of the Software
|
|
17
|
+
- Reverse engineer, disassemble, decompile, or otherwise attempt to derive
|
|
18
|
+
the source code of the Software
|
|
19
|
+
- Redistribute, sublicense, lease, rent, or lend the Software to third parties
|
|
20
|
+
- Remove or alter any proprietary notices, labels, or marks on the Software
|
|
21
|
+
- Use the Software for any purpose other than as expressly permitted herein
|
|
22
|
+
|
|
23
|
+
NO WARRANTY:
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL YAK
|
|
27
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
28
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
29
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
30
|
+
|
|
31
|
+
TERMINATION:
|
|
32
|
+
This license is effective until terminated. Your rights under this license
|
|
33
|
+
will terminate automatically without notice if you fail to comply with any
|
|
34
|
+
of its terms.
|
|
35
|
+
|
|
36
|
+
For licensing inquiries, contact: support@yak.io
|
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @yak-io/trpc
|
|
2
|
+
|
|
3
|
+
Adapters that turn tRPC procedures into Yak tool definitions. This package plugs directly into `@yak-io/javascript` and works seamlessly with the Next.js helpers.
|
|
4
|
+
|
|
5
|
+
## What you get
|
|
6
|
+
|
|
7
|
+
- `createTRPCToolExecutor` – a thin wrapper that turns procedure names into a tool executor function.
|
|
8
|
+
- `createTRPCToolAdapter` – a higher level helper that returns a full `ToolSource` (manifest + executor) that can be passed straight into `createYakHandler` or `createNextYakHandler`.
|
|
9
|
+
- `buildToolManifest` – introspection utility used by the adapter (exposed for custom pipelines).
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add @yak-io/trpc @yak-io/javascript
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
You also need `@trpc/server` (v10+ or v11+) in your project.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### 1. Build a tRPC adapter
|
|
22
|
+
|
|
23
|
+
By default, all procedures from your router are exposed as tools:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { createTRPCToolAdapter } from "@yak-io/trpc";
|
|
27
|
+
import { appRouter, createContext } from "@/server/trpc";
|
|
28
|
+
|
|
29
|
+
// All procedures are available
|
|
30
|
+
const trpcTools = createTRPCToolAdapter({
|
|
31
|
+
router: appRouter,
|
|
32
|
+
createContext: async ({ req }) => createContext({ req }),
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#### Restricting procedures
|
|
37
|
+
|
|
38
|
+
Use `allowedProcedures` to whitelist specific procedures:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const trpcTools = createTRPCToolAdapter({
|
|
42
|
+
router: appRouter,
|
|
43
|
+
createContext: async ({ req }) => createContext({ req }),
|
|
44
|
+
allowedProcedures: ["orders.list", "orders.detail"],
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Use `disallowedProcedures` to block specific procedures while allowing the rest:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const trpcTools = createTRPCToolAdapter({
|
|
52
|
+
router: appRouter,
|
|
53
|
+
createContext: async ({ req }) => createContext({ req }),
|
|
54
|
+
disallowedProcedures: ["admin.deleteUser", "billing.refund"],
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Attach it to a Yak handler
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { createYakHandler } from "@yak-io/javascript/server";
|
|
62
|
+
|
|
63
|
+
export const { GET, POST } = createYakHandler({
|
|
64
|
+
routes: () => Promise.resolve([{ path: "/" }]),
|
|
65
|
+
tools: trpcTools,
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
If you are in a Next.js app, simply pass the adapter to `createNextYakHandler` instead.
|
|
70
|
+
|
|
71
|
+
### 3. Executor only
|
|
72
|
+
|
|
73
|
+
If you already generate manifests elsewhere you can still use the lower level executor helper:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { createTRPCToolExecutor } from "@yak-io/trpc";
|
|
77
|
+
|
|
78
|
+
const executeTool = createTRPCToolExecutor({
|
|
79
|
+
router: appRouter,
|
|
80
|
+
createContext,
|
|
81
|
+
allowedProcedures: ["orders.list"],
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Then supply `getTools` + `executeTool` to any Yak handler.
|
|
86
|
+
|
|
87
|
+
## Types
|
|
88
|
+
|
|
89
|
+
All tool/route/chat config types are re-exported from `@yak-io/javascript/server`, e.g.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import type { ToolDefinition, ToolManifest, ToolExecutor } from "@yak-io/trpc";
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Security tips
|
|
96
|
+
|
|
97
|
+
- For production apps, consider using `allowedProcedures` to restrict to the minimal surface area needed by the assistant, or use `disallowedProcedures` to block sensitive operations.
|
|
98
|
+
- Build per-request contexts so each call is authorized with the user session from `req`.
|
|
99
|
+
- Combine the adapter with additional `ToolSource`s (e.g., GraphQL or REST) by passing arrays to `createYakHandler` / `createNextYakHandler`.
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
Proprietary - see LICENSE file
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { AnyRouter } from "@trpc/server";
|
|
2
|
+
import type { ToolExecutor, ToolSource } from "@yak-io/javascript/server";
|
|
3
|
+
/**
|
|
4
|
+
* Generic request type that works with Next.js Request
|
|
5
|
+
*/
|
|
6
|
+
export type GenericRequest = {
|
|
7
|
+
json(): Promise<unknown>;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for creating a tRPC tool executor
|
|
11
|
+
*/
|
|
12
|
+
export type TRPCToolExecutorConfig<TRouter extends AnyRouter, TContext, TRequest extends GenericRequest = GenericRequest> = {
|
|
13
|
+
/** tRPC router instance */
|
|
14
|
+
router: TRouter;
|
|
15
|
+
/** Function to create tRPC context from request */
|
|
16
|
+
createContext: (opts: {
|
|
17
|
+
req: TRequest;
|
|
18
|
+
}) => Promise<TContext>;
|
|
19
|
+
/**
|
|
20
|
+
* List of allowed procedure paths, e.g. ["orders.list", "user.updateProfile"].
|
|
21
|
+
* If provided, only these procedures can be invoked as tools.
|
|
22
|
+
* If omitted, all procedures are allowed by default.
|
|
23
|
+
*/
|
|
24
|
+
allowedProcedures?: string[];
|
|
25
|
+
/**
|
|
26
|
+
* List of disallowed procedure paths, e.g. ["admin.deleteUser", "billing.refund"].
|
|
27
|
+
* These procedures will be excluded even if they would otherwise be allowed.
|
|
28
|
+
* Applied after allowedProcedures filtering.
|
|
29
|
+
*/
|
|
30
|
+
disallowedProcedures?: string[];
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Creates a tool executor function that uses tRPC to execute procedures
|
|
34
|
+
*
|
|
35
|
+
* This adapter allows you to use tRPC procedures as chatbot tools with the
|
|
36
|
+
* Next.js handler from @yak-io/nextjs/server
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* // app/api/yak/tools/route.ts
|
|
41
|
+
* import { createNextYakToolsHandler } from "@yak-io/nextjs/server";
|
|
42
|
+
* import { createTRPCToolExecutor } from "@yak-io/trpc";
|
|
43
|
+
* import { appRouter } from "@/server/trpc/router";
|
|
44
|
+
* import { createContext } from "@/server/trpc/context";
|
|
45
|
+
*
|
|
46
|
+
* export const POST = createNextYakToolsHandler({
|
|
47
|
+
* executeTool: createTRPCToolExecutor({
|
|
48
|
+
* router: appRouter,
|
|
49
|
+
* createContext,
|
|
50
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"],
|
|
51
|
+
* }),
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function createTRPCToolExecutor<TRouter extends AnyRouter, TContext, TRequest extends GenericRequest = GenericRequest>(config: TRPCToolExecutorConfig<TRouter, TContext, TRequest>): ToolExecutor;
|
|
56
|
+
export type TRPCToolAdapterConfig<TRouter extends AnyRouter, TContext, TRequest extends GenericRequest = GenericRequest> = TRPCToolExecutorConfig<TRouter, TContext, TRequest> & {
|
|
57
|
+
id?: string;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Create a core compatible tool source that bundles manifest + executor
|
|
61
|
+
*/
|
|
62
|
+
export declare function createTRPCToolAdapter<TRouter extends AnyRouter, TContext, TRequest extends GenericRequest = GenericRequest>(config: TRPCToolAdapterConfig<TRouter, TContext, TRequest>): ToolSource;
|
|
63
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG1E;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,CAAC,OAAO,SAAS,SAAS,EAAE,QAAQ,EAAE,QAAQ,SAAS,cAAc,GAAG,cAAc,IAAI;IAC1H,2BAA2B;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,mDAAmD;IACnD,aAAa,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9D;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,SAAS,SAAS,EACzB,QAAQ,EACR,QAAQ,SAAS,cAAc,GAAG,cAAc,EAEhD,MAAM,EAAE,sBAAsB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAC1D,YAAY,CAyBd;AAED,MAAM,MAAM,qBAAqB,CAC/B,OAAO,SAAS,SAAS,EACzB,QAAQ,EACR,QAAQ,SAAS,cAAc,GAAG,cAAc,IAC9C,sBAAsB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG;IACxD,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,SAAS,SAAS,EACzB,QAAQ,EACR,QAAQ,SAAS,cAAc,GAAG,cAAc,EAChD,MAAM,EAAE,qBAAqB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,UAAU,CAYxE"}
|
package/dist/adapters.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createDynamicCaller } from "./caller.js";
|
|
2
|
+
import { buildToolManifest } from "./introspect.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a tool executor function that uses tRPC to execute procedures
|
|
5
|
+
*
|
|
6
|
+
* This adapter allows you to use tRPC procedures as chatbot tools with the
|
|
7
|
+
* Next.js handler from @yak-io/nextjs/server
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // app/api/yak/tools/route.ts
|
|
12
|
+
* import { createNextYakToolsHandler } from "@yak-io/nextjs/server";
|
|
13
|
+
* import { createTRPCToolExecutor } from "@yak-io/trpc";
|
|
14
|
+
* import { appRouter } from "@/server/trpc/router";
|
|
15
|
+
* import { createContext } from "@/server/trpc/context";
|
|
16
|
+
*
|
|
17
|
+
* export const POST = createNextYakToolsHandler({
|
|
18
|
+
* executeTool: createTRPCToolExecutor({
|
|
19
|
+
* router: appRouter,
|
|
20
|
+
* createContext,
|
|
21
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"],
|
|
22
|
+
* }),
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function createTRPCToolExecutor(config) {
|
|
27
|
+
const { router, createContext, allowedProcedures, disallowedProcedures } = config;
|
|
28
|
+
const allowedSet = allowedProcedures ? new Set(allowedProcedures) : null;
|
|
29
|
+
const disallowedSet = disallowedProcedures ? new Set(disallowedProcedures) : null;
|
|
30
|
+
return async (name, args, req) => {
|
|
31
|
+
// Check if procedure is allowed
|
|
32
|
+
// If allowedProcedures is set, procedure must be in the list
|
|
33
|
+
if (allowedSet && !allowedSet.has(name)) {
|
|
34
|
+
throw new Error(`Procedure '${name}' is not allowed`);
|
|
35
|
+
}
|
|
36
|
+
// If disallowedProcedures is set, procedure must not be in the list
|
|
37
|
+
if (disallowedSet && disallowedSet.has(name)) {
|
|
38
|
+
throw new Error(`Procedure '${name}' is not allowed`);
|
|
39
|
+
}
|
|
40
|
+
// Create tRPC context
|
|
41
|
+
const ctx = await createContext({ req: req });
|
|
42
|
+
// Create dynamic caller
|
|
43
|
+
const caller = createDynamicCaller(router, ctx);
|
|
44
|
+
// Invoke the procedure
|
|
45
|
+
return caller(name, args);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create a core compatible tool source that bundles manifest + executor
|
|
50
|
+
*/
|
|
51
|
+
export function createTRPCToolAdapter(config) {
|
|
52
|
+
return {
|
|
53
|
+
id: config.id ?? "trpc",
|
|
54
|
+
getTools: async () => {
|
|
55
|
+
const manifest = buildToolManifest(config.router, {
|
|
56
|
+
allowedProcedures: config.allowedProcedures,
|
|
57
|
+
disallowedProcedures: config.disallowedProcedures,
|
|
58
|
+
});
|
|
59
|
+
return manifest.tools;
|
|
60
|
+
},
|
|
61
|
+
executeTool: createTRPCToolExecutor(config),
|
|
62
|
+
};
|
|
63
|
+
}
|
package/dist/caller.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Coerces input values based on Zod schema types.
|
|
4
|
+
* Converts ISO date strings to Date objects only for z.date() fields.
|
|
5
|
+
* Leaves z.string() fields unchanged even if they contain ISO date strings.
|
|
6
|
+
*/
|
|
7
|
+
export declare function coerceInputToSchema(input: unknown, schema: ZodType | undefined): unknown;
|
|
8
|
+
/**
|
|
9
|
+
* Splits a procedure path like "orders.list" into ["orders", "list"]
|
|
10
|
+
*/
|
|
11
|
+
export declare function splitProcedurePath(path: string): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Creates a dynamic caller that can invoke procedures by path string.
|
|
14
|
+
* Drills into nested router structure to find the target procedure.
|
|
15
|
+
* Automatically coerces ISO date strings to Date objects for z.date() fields.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const caller = createDynamicCaller(appRouter, ctx);
|
|
20
|
+
* const result = await caller("orders.list", { limit: 10 });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function createDynamicCaller(router: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
24
|
+
ctx: any): (name: string, input: unknown) => Promise<unknown>;
|
|
25
|
+
//# sourceMappingURL=caller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caller.d.ts","sourceRoot":"","sources":["../src/caller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAuEnC;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,GAAG,SAAS,GAC1B,OAAO,CA4DT;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,GAAG,EAAE,yDAAyD;AACtE,GAAG,EAAE,GAAG,GACP,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CA+CpD"}
|
package/dist/caller.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Properties that must never be accessed dynamically to prevent prototype pollution
|
|
3
|
+
*/
|
|
4
|
+
const FORBIDDEN_PROPS = new Set(["__proto__", "constructor", "prototype"]);
|
|
5
|
+
/**
|
|
6
|
+
* ISO 8601 date string pattern
|
|
7
|
+
* Matches: 2024-01-15T10:30:00.000Z, 2024-01-15T10:30:00Z, 2024-01-15T10:30:00+00:00
|
|
8
|
+
*/
|
|
9
|
+
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
10
|
+
/**
|
|
11
|
+
* Gets the Zod type name from a schema (supports both Zod 3 and Zod 4)
|
|
12
|
+
*/
|
|
13
|
+
function getZodTypeName(schema) {
|
|
14
|
+
// Zod 4 uses schema.type or schema._def.type
|
|
15
|
+
// Zod 3 uses schema._def.typeName
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
const s = schema;
|
|
18
|
+
return s.type ?? s._def?.type ?? s._def?.typeName;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Gets the inner type from wrapper Zod types (optional, nullable, default, etc.)
|
|
22
|
+
*/
|
|
23
|
+
function unwrapZodType(schema) {
|
|
24
|
+
const typeName = getZodTypeName(schema);
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
const def = schema._def;
|
|
27
|
+
if (typeName === "optional" ||
|
|
28
|
+
typeName === "ZodOptional" ||
|
|
29
|
+
typeName === "nullable" ||
|
|
30
|
+
typeName === "ZodNullable" ||
|
|
31
|
+
typeName === "default" ||
|
|
32
|
+
typeName === "ZodDefault") {
|
|
33
|
+
// Zod 4 uses def.innerType, Zod 3 uses def.innerType
|
|
34
|
+
const inner = def.innerType ?? def.unwrap?.();
|
|
35
|
+
if (inner)
|
|
36
|
+
return unwrapZodType(inner);
|
|
37
|
+
}
|
|
38
|
+
return schema;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Checks if a Zod schema represents a date type
|
|
42
|
+
*/
|
|
43
|
+
function isZodDate(schema) {
|
|
44
|
+
const unwrapped = unwrapZodType(schema);
|
|
45
|
+
const typeName = getZodTypeName(unwrapped);
|
|
46
|
+
return typeName === "date" || typeName === "ZodDate";
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Gets the shape of a Zod object schema (supports both Zod 3 and Zod 4)
|
|
50
|
+
*/
|
|
51
|
+
function getObjectShape(schema) {
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
+
const def = schema._def;
|
|
54
|
+
// Zod 4: def.shape is an object
|
|
55
|
+
// Zod 3: def.shape() is a function
|
|
56
|
+
if (typeof def.shape === "function") {
|
|
57
|
+
return def.shape();
|
|
58
|
+
}
|
|
59
|
+
return def.shape;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Coerces input values based on Zod schema types.
|
|
63
|
+
* Converts ISO date strings to Date objects only for z.date() fields.
|
|
64
|
+
* Leaves z.string() fields unchanged even if they contain ISO date strings.
|
|
65
|
+
*/
|
|
66
|
+
export function coerceInputToSchema(input, schema) {
|
|
67
|
+
if (input === null || input === undefined || !schema) {
|
|
68
|
+
return input;
|
|
69
|
+
}
|
|
70
|
+
const unwrapped = unwrapZodType(schema);
|
|
71
|
+
const typeName = getZodTypeName(unwrapped);
|
|
72
|
+
// Handle date coercion
|
|
73
|
+
if ((typeName === "date" || typeName === "ZodDate") && typeof input === "string") {
|
|
74
|
+
if (ISO_DATE_REGEX.test(input)) {
|
|
75
|
+
const date = new Date(input);
|
|
76
|
+
if (!Number.isNaN(date.getTime())) {
|
|
77
|
+
return date;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return input;
|
|
81
|
+
}
|
|
82
|
+
// Handle arrays
|
|
83
|
+
if ((typeName === "array" || typeName === "ZodArray") && Array.isArray(input)) {
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
|
+
const def = unwrapped._def;
|
|
86
|
+
const elementSchema = def.type ?? def.element;
|
|
87
|
+
return input.map((item) => coerceInputToSchema(item, elementSchema));
|
|
88
|
+
}
|
|
89
|
+
// Handle objects
|
|
90
|
+
if ((typeName === "object" || typeName === "ZodObject") && typeof input === "object") {
|
|
91
|
+
const shape = getObjectShape(unwrapped);
|
|
92
|
+
if (!shape)
|
|
93
|
+
return input;
|
|
94
|
+
const result = {};
|
|
95
|
+
for (const [key, value] of Object.entries(input)) {
|
|
96
|
+
const fieldSchema = shape[key];
|
|
97
|
+
result[key] = fieldSchema
|
|
98
|
+
? coerceInputToSchema(value, fieldSchema)
|
|
99
|
+
: value;
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
// Handle unions (e.g., z.union([z.string(), z.date()]))
|
|
104
|
+
if ((typeName === "union" || typeName === "ZodUnion") && typeof input === "string") {
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
106
|
+
const def = unwrapped._def;
|
|
107
|
+
const options = def.options;
|
|
108
|
+
if (options) {
|
|
109
|
+
// If any option is a date and input looks like a date, coerce it
|
|
110
|
+
const hasDateOption = options.some((opt) => isZodDate(opt));
|
|
111
|
+
if (hasDateOption && ISO_DATE_REGEX.test(input)) {
|
|
112
|
+
const date = new Date(input);
|
|
113
|
+
if (!Number.isNaN(date.getTime())) {
|
|
114
|
+
return date;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return input;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Splits a procedure path like "orders.list" into ["orders", "list"]
|
|
123
|
+
*/
|
|
124
|
+
export function splitProcedurePath(path) {
|
|
125
|
+
return path.split(".");
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Creates a dynamic caller that can invoke procedures by path string.
|
|
129
|
+
* Drills into nested router structure to find the target procedure.
|
|
130
|
+
* Automatically coerces ISO date strings to Date objects for z.date() fields.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* const caller = createDynamicCaller(appRouter, ctx);
|
|
135
|
+
* const result = await caller("orders.list", { limit: 10 });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export function createDynamicCaller(router, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
139
|
+
ctx // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
140
|
+
) {
|
|
141
|
+
const caller = router.createCaller(ctx);
|
|
142
|
+
// Get procedure definitions for schema lookup
|
|
143
|
+
const procedures = router._def.procedures; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
144
|
+
return async (name, input) => {
|
|
145
|
+
const pathParts = splitProcedurePath(name);
|
|
146
|
+
let current = caller; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
147
|
+
// Drill down to the target procedure
|
|
148
|
+
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
149
|
+
const part = pathParts[i];
|
|
150
|
+
if (!part) {
|
|
151
|
+
throw new Error(`Invalid procedure path: ${name}`);
|
|
152
|
+
}
|
|
153
|
+
// Prevent prototype pollution attacks
|
|
154
|
+
if (FORBIDDEN_PROPS.has(part)) {
|
|
155
|
+
throw new Error(`Invalid procedure path: ${name}`);
|
|
156
|
+
}
|
|
157
|
+
current = current[part];
|
|
158
|
+
if (!current) {
|
|
159
|
+
throw new Error(`Procedure not found: ${name}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Call the final procedure
|
|
163
|
+
const procedureName = pathParts[pathParts.length - 1];
|
|
164
|
+
if (!procedureName) {
|
|
165
|
+
throw new Error(`Invalid procedure path: ${name}`);
|
|
166
|
+
}
|
|
167
|
+
// Prevent prototype pollution attacks
|
|
168
|
+
if (FORBIDDEN_PROPS.has(procedureName)) {
|
|
169
|
+
throw new Error(`Invalid procedure path: ${name}`);
|
|
170
|
+
}
|
|
171
|
+
const procedure = current[procedureName];
|
|
172
|
+
if (typeof procedure !== "function") {
|
|
173
|
+
throw new Error(`Procedure not found or not callable: ${name}`);
|
|
174
|
+
}
|
|
175
|
+
// Get input schema and coerce dates based on schema types
|
|
176
|
+
const procDef = procedures[name];
|
|
177
|
+
const inputSchema = procDef?._def?.inputs?.[0];
|
|
178
|
+
const coercedInput = coerceInputToSchema(input, inputSchema);
|
|
179
|
+
return procedure(coercedInput);
|
|
180
|
+
};
|
|
181
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AnyRouter } from "@trpc/server";
|
|
2
|
+
import type { RouteInfo } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for the chat config handler
|
|
5
|
+
*/
|
|
6
|
+
export type NextChatbotConfigHandlerConfig<TRouter extends AnyRouter> = {
|
|
7
|
+
/**
|
|
8
|
+
* The tRPC router to introspect for tools
|
|
9
|
+
*/
|
|
10
|
+
router: TRouter;
|
|
11
|
+
/**
|
|
12
|
+
* List of allowed procedure paths for tools
|
|
13
|
+
*/
|
|
14
|
+
allowedProcedures: string[];
|
|
15
|
+
/**
|
|
16
|
+
* Function to get route information
|
|
17
|
+
* This should scan your Next.js app directory and return route info
|
|
18
|
+
*/
|
|
19
|
+
getRoutes: () => Promise<RouteInfo[]>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Create a Next.js App Router handler that exposes combined chat configuration
|
|
23
|
+
*
|
|
24
|
+
* This handler combines both the tool manifest (tRPC procedures) and route manifest
|
|
25
|
+
* (Next.js routes) into a single endpoint for the chatbot to consume.
|
|
26
|
+
*
|
|
27
|
+
* @param config - Configuration object
|
|
28
|
+
* @returns A Next.js route handler function
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* // app/api/chatbot/config/route.ts
|
|
33
|
+
* import { appRouter } from "@/server/trpc/router";
|
|
34
|
+
* import { createNextChatbotConfigHandler } from "@yak/trpc";
|
|
35
|
+
* import { scanRoutes } from "@yak/nextjs/server";
|
|
36
|
+
*
|
|
37
|
+
* export const GET = createNextChatbotConfigHandler({
|
|
38
|
+
* router: appRouter,
|
|
39
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"],
|
|
40
|
+
* getRoutes: async () => {
|
|
41
|
+
* return scanRoutes("./src/app", false);
|
|
42
|
+
* },
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function createNextChatbotConfigHandler<TRouter extends AnyRouter>(config: NextChatbotConfigHandlerConfig<TRouter>): (_req: Request) => Promise<Response>;
|
|
47
|
+
//# sourceMappingURL=createNextChatbotConfigHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNextChatbotConfigHandler.d.ts","sourceRoot":"","sources":["../src/createNextChatbotConfigHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,YAAY,CAAC;AAGxD;;GAEG;AACH,MAAM,MAAM,8BAA8B,CAAC,OAAO,SAAS,SAAS,IAAI;IACtE;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAE5B;;;OAGG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;CACvC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,SAAS,SAAS,EAEzB,MAAM,EAAE,8BAA8B,CAAC,OAAO,CAAC,IAG7C,MAAM,OAAO,KACZ,OAAO,CAAC,QAAQ,CAAC,CAwBrB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { buildToolManifest } from "./introspect.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a Next.js App Router handler that exposes combined chat configuration
|
|
4
|
+
*
|
|
5
|
+
* This handler combines both the tool manifest (tRPC procedures) and route manifest
|
|
6
|
+
* (Next.js routes) into a single endpoint for the chatbot to consume.
|
|
7
|
+
*
|
|
8
|
+
* @param config - Configuration object
|
|
9
|
+
* @returns A Next.js route handler function
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // app/api/chatbot/config/route.ts
|
|
14
|
+
* import { appRouter } from "@/server/trpc/router";
|
|
15
|
+
* import { createNextChatbotConfigHandler } from "@yak/trpc";
|
|
16
|
+
* import { scanRoutes } from "@yak/nextjs/server";
|
|
17
|
+
*
|
|
18
|
+
* export const GET = createNextChatbotConfigHandler({
|
|
19
|
+
* router: appRouter,
|
|
20
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"],
|
|
21
|
+
* getRoutes: async () => {
|
|
22
|
+
* return scanRoutes("./src/app", false);
|
|
23
|
+
* },
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function createNextChatbotConfigHandler(config) {
|
|
28
|
+
return async function handleConfig(_req) {
|
|
29
|
+
const toolManifest = buildToolManifest(config.router, {
|
|
30
|
+
allowedProcedures: config.allowedProcedures,
|
|
31
|
+
});
|
|
32
|
+
const routes = await config.getRoutes();
|
|
33
|
+
const routeManifest = {
|
|
34
|
+
routes,
|
|
35
|
+
generated_at: new Date().toISOString(),
|
|
36
|
+
};
|
|
37
|
+
const chatConfig = {
|
|
38
|
+
tools: toolManifest,
|
|
39
|
+
routes: routeManifest,
|
|
40
|
+
};
|
|
41
|
+
return new Response(JSON.stringify(chatConfig), {
|
|
42
|
+
status: 200,
|
|
43
|
+
headers: {
|
|
44
|
+
"Content-Type": "application/json",
|
|
45
|
+
"Cache-Control": "no-store",
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AnyRouter } from "@trpc/server";
|
|
2
|
+
/**
|
|
3
|
+
* Generic request type
|
|
4
|
+
*/
|
|
5
|
+
export type GenericRequest = {
|
|
6
|
+
json(): Promise<unknown>;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for the tool manifest handler
|
|
10
|
+
*/
|
|
11
|
+
export type NextChatbotToolManifestHandlerConfig<TRouter extends AnyRouter> = {
|
|
12
|
+
/**
|
|
13
|
+
* The tRPC router to introspect
|
|
14
|
+
*/
|
|
15
|
+
router: TRouter;
|
|
16
|
+
/**
|
|
17
|
+
* List of allowed procedure paths, e.g. ["orders.list", "user.updateProfile"].
|
|
18
|
+
* Only these procedures will appear in the tool manifest.
|
|
19
|
+
*/
|
|
20
|
+
allowedProcedures: string[];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Create a Next.js App Router handler that exposes a tool manifest
|
|
24
|
+
*
|
|
25
|
+
* This handler introspects your tRPC router at runtime and returns a JSON manifest
|
|
26
|
+
* of tools (procedures) available to the chatbot, including their input/output schemas.
|
|
27
|
+
*
|
|
28
|
+
* @param config - Configuration object
|
|
29
|
+
* @returns A Next.js route handler function
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* // app/api/chatbot/tools/manifest/route.ts
|
|
34
|
+
* import { appRouter } from "@/server/trpc/router";
|
|
35
|
+
* import { createNextChatbotToolManifestHandler } from "@yak/trpc";
|
|
36
|
+
*
|
|
37
|
+
* export const GET = createNextChatbotToolManifestHandler({
|
|
38
|
+
* router: appRouter,
|
|
39
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"],
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function createNextChatbotToolManifestHandler<TRouter extends AnyRouter>(config: NextChatbotToolManifestHandlerConfig<TRouter>): (_req: GenericRequest) => Promise<Response>;
|
|
44
|
+
//# sourceMappingURL=createNextChatbotToolManifestHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNextChatbotToolManifestHandler.d.ts","sourceRoot":"","sources":["../src/createNextChatbotToolManifestHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oCAAoC,CAAC,OAAO,SAAS,SAAS,IAAI;IAC5E;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oCAAoC,CAClD,OAAO,SAAS,SAAS,EAEzB,MAAM,EAAE,oCAAoC,CAAC,OAAO,CAAC,IAGnD,MAAM,cAAc,KACnB,OAAO,CAAC,QAAQ,CAAC,CAarB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { buildToolManifest } from "./introspect.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a Next.js App Router handler that exposes a tool manifest
|
|
4
|
+
*
|
|
5
|
+
* This handler introspects your tRPC router at runtime and returns a JSON manifest
|
|
6
|
+
* of tools (procedures) available to the chatbot, including their input/output schemas.
|
|
7
|
+
*
|
|
8
|
+
* @param config - Configuration object
|
|
9
|
+
* @returns A Next.js route handler function
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // app/api/chatbot/tools/manifest/route.ts
|
|
14
|
+
* import { appRouter } from "@/server/trpc/router";
|
|
15
|
+
* import { createNextChatbotToolManifestHandler } from "@yak/trpc";
|
|
16
|
+
*
|
|
17
|
+
* export const GET = createNextChatbotToolManifestHandler({
|
|
18
|
+
* router: appRouter,
|
|
19
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"],
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function createNextChatbotToolManifestHandler(config) {
|
|
24
|
+
return async function handleManifest(_req) {
|
|
25
|
+
const manifest = buildToolManifest(config.router, {
|
|
26
|
+
allowedProcedures: config.allowedProcedures,
|
|
27
|
+
});
|
|
28
|
+
return new Response(JSON.stringify(manifest), {
|
|
29
|
+
status: 200,
|
|
30
|
+
headers: {
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
"Cache-Control": "no-store",
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { AnyRouter } from "@trpc/server";
|
|
2
|
+
/**
|
|
3
|
+
* Generic request type that works with Next.js Request
|
|
4
|
+
*/
|
|
5
|
+
export type GenericRequest = {
|
|
6
|
+
json(): Promise<unknown>;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for the Next.js chatbot tools handler
|
|
10
|
+
*/
|
|
11
|
+
export type NextChatbotToolsHandlerConfig<TRouter extends AnyRouter, TContext, TRequest extends GenericRequest = GenericRequest> = {
|
|
12
|
+
/** tRPC router instance */
|
|
13
|
+
router: TRouter;
|
|
14
|
+
/** Function to create tRPC context from request */
|
|
15
|
+
createContext: (opts: {
|
|
16
|
+
req: TRequest;
|
|
17
|
+
}) => Promise<TContext>;
|
|
18
|
+
/**
|
|
19
|
+
* List of allowed procedure paths, e.g. ["orders.list", "user.updateProfile"].
|
|
20
|
+
* Only these procedures can be invoked as tools.
|
|
21
|
+
*/
|
|
22
|
+
allowedProcedures: string[];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Creates a Next.js App Router-compatible POST handler for chatbot tool calls.
|
|
26
|
+
*
|
|
27
|
+
* This handler:
|
|
28
|
+
* 1. Parses the tool call payload from the request
|
|
29
|
+
* 2. Validates the procedure name is in the allowlist
|
|
30
|
+
* 3. Creates a tRPC caller with the request context
|
|
31
|
+
* 4. Dynamically invokes the requested procedure
|
|
32
|
+
* 5. Returns the result or error as JSON
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* // app/api/chatbot/tools/route.ts
|
|
37
|
+
* import { NextRequest } from "next/server";
|
|
38
|
+
* import { appRouter } from "@/server/trpc/router";
|
|
39
|
+
* import { createContext } from "@/server/trpc/context";
|
|
40
|
+
* import { createNextChatbotToolsHandler } from "@yak/trpc";
|
|
41
|
+
*
|
|
42
|
+
* export const POST = createNextChatbotToolsHandler({
|
|
43
|
+
* router: appRouter,
|
|
44
|
+
* createContext,
|
|
45
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"],
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function createNextChatbotToolsHandler<TRouter extends AnyRouter, TContext, TRequest extends GenericRequest = GenericRequest>(config: NextChatbotToolsHandlerConfig<TRouter, TContext, TRequest>): (req: TRequest) => Promise<Response>;
|
|
50
|
+
//# sourceMappingURL=createNextChatbotToolsHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNextChatbotToolsHandler.d.ts","sourceRoot":"","sources":["../src/createNextChatbotToolsHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAK9C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,CAAC,OAAO,SAAS,SAAS,EAAE,QAAQ,EAAE,QAAQ,SAAS,cAAc,GAAG,cAAc,IAAI;IACjI,2BAA2B;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,mDAAmD;IACnD,aAAa,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9D;;;OAGG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,SAAS,SAAS,EACzB,QAAQ,EACR,QAAQ,SAAS,cAAc,GAAG,cAAc,EAEhD,MAAM,EAAE,6BAA6B,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,GACjE,CAAC,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC,CA8DtC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { createDynamicCaller } from "./caller.js";
|
|
2
|
+
import { logger } from "./logger.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a Next.js App Router-compatible POST handler for chatbot tool calls.
|
|
5
|
+
*
|
|
6
|
+
* This handler:
|
|
7
|
+
* 1. Parses the tool call payload from the request
|
|
8
|
+
* 2. Validates the procedure name is in the allowlist
|
|
9
|
+
* 3. Creates a tRPC caller with the request context
|
|
10
|
+
* 4. Dynamically invokes the requested procedure
|
|
11
|
+
* 5. Returns the result or error as JSON
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // app/api/chatbot/tools/route.ts
|
|
16
|
+
* import { NextRequest } from "next/server";
|
|
17
|
+
* import { appRouter } from "@/server/trpc/router";
|
|
18
|
+
* import { createContext } from "@/server/trpc/context";
|
|
19
|
+
* import { createNextChatbotToolsHandler } from "@yak/trpc";
|
|
20
|
+
*
|
|
21
|
+
* export const POST = createNextChatbotToolsHandler({
|
|
22
|
+
* router: appRouter,
|
|
23
|
+
* createContext,
|
|
24
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"],
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function createNextChatbotToolsHandler(config) {
|
|
29
|
+
const { router, createContext, allowedProcedures } = config;
|
|
30
|
+
return async (req) => {
|
|
31
|
+
try {
|
|
32
|
+
// Parse request body
|
|
33
|
+
const body = await req.json();
|
|
34
|
+
// Validate payload structure
|
|
35
|
+
if (!isToolCallPayload(body)) {
|
|
36
|
+
logger.warn("Invalid tool call payload received");
|
|
37
|
+
return createErrorResponse("Invalid request payload", 400);
|
|
38
|
+
}
|
|
39
|
+
const { id, name, args } = body;
|
|
40
|
+
logger.debug(`Tool call received: ${name}`, { id, args });
|
|
41
|
+
// Check if procedure is allowed
|
|
42
|
+
if (!allowedProcedures.includes(name)) {
|
|
43
|
+
logger.warn(`Procedure not allowed: ${name}`);
|
|
44
|
+
return createToolErrorResponse(id, `Procedure '${name}' is not allowed`);
|
|
45
|
+
}
|
|
46
|
+
// Create tRPC context
|
|
47
|
+
const ctx = await createContext({ req });
|
|
48
|
+
// Create dynamic caller
|
|
49
|
+
const caller = createDynamicCaller(router, ctx);
|
|
50
|
+
// Invoke the procedure
|
|
51
|
+
const result = await caller(name, args);
|
|
52
|
+
logger.debug(`Tool call succeeded: ${name}`, { id });
|
|
53
|
+
// Return success response
|
|
54
|
+
const successResult = {
|
|
55
|
+
id,
|
|
56
|
+
ok: true,
|
|
57
|
+
result,
|
|
58
|
+
};
|
|
59
|
+
return new Response(JSON.stringify(successResult), {
|
|
60
|
+
status: 200,
|
|
61
|
+
headers: {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
logger.error("Tool call failed", error);
|
|
68
|
+
// Extract error details
|
|
69
|
+
const body = await req.json().catch(() => ({}));
|
|
70
|
+
const id = body.id ?? "unknown";
|
|
71
|
+
const errorMessage = extractErrorMessage(error);
|
|
72
|
+
return createToolErrorResponse(id, errorMessage);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Type guard to validate tool call payload
|
|
78
|
+
*/
|
|
79
|
+
function isToolCallPayload(payload) {
|
|
80
|
+
return (typeof payload === "object" &&
|
|
81
|
+
payload !== null &&
|
|
82
|
+
"id" in payload &&
|
|
83
|
+
typeof payload.id === "string" &&
|
|
84
|
+
"name" in payload &&
|
|
85
|
+
typeof payload.name === "string" &&
|
|
86
|
+
"args" in payload);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Extract a safe error message from an unknown error
|
|
90
|
+
*/
|
|
91
|
+
function extractErrorMessage(error) {
|
|
92
|
+
if (error instanceof Error) {
|
|
93
|
+
return error.message;
|
|
94
|
+
}
|
|
95
|
+
if (typeof error === "string") {
|
|
96
|
+
return error;
|
|
97
|
+
}
|
|
98
|
+
return "An unknown error occurred";
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create a JSON response for tool call errors
|
|
102
|
+
*/
|
|
103
|
+
function createToolErrorResponse(id, error) {
|
|
104
|
+
const errorResult = {
|
|
105
|
+
id,
|
|
106
|
+
ok: false,
|
|
107
|
+
error,
|
|
108
|
+
};
|
|
109
|
+
return new Response(JSON.stringify(errorResult), {
|
|
110
|
+
status: 200, // Return 200 with error payload so client can process it
|
|
111
|
+
headers: {
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Create a generic HTTP error response
|
|
118
|
+
*/
|
|
119
|
+
function createErrorResponse(message, status) {
|
|
120
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
121
|
+
status,
|
|
122
|
+
headers: {
|
|
123
|
+
"Content-Type": "application/json",
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createTRPCToolExecutor, createTRPCToolAdapter } from "./adapters.js";
|
|
2
|
+
export type { TRPCToolExecutorConfig, TRPCToolAdapterConfig } from "./adapters.js";
|
|
3
|
+
export { buildToolManifest } from "./introspect.js";
|
|
4
|
+
export type { BuildToolManifestOptions } from "./introspect.js";
|
|
5
|
+
export type { ToolCallPayload, ToolCallResult, ToolDefinition, ToolManifest, RouteInfo, RouteManifest, ChatConfig, ToolExecutor, } from "@yak-io/javascript/server";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC9E,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAGhE,YAAY,EACX,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,EACV,YAAY,GACZ,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AnyRouter } from "@trpc/server";
|
|
2
|
+
import type { ToolManifest } from "@yak-io/javascript/server";
|
|
3
|
+
/**
|
|
4
|
+
* Options for building a tool manifest
|
|
5
|
+
*/
|
|
6
|
+
export type BuildToolManifestOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* List of procedure paths to include (e.g., ["orders.list", "user.updateProfile"]).
|
|
9
|
+
* If omitted, all procedures are included by default.
|
|
10
|
+
*/
|
|
11
|
+
allowedProcedures?: string[];
|
|
12
|
+
/**
|
|
13
|
+
* List of procedure paths to exclude (e.g., ["admin.deleteUser", "billing.refund"]).
|
|
14
|
+
* Applied after allowedProcedures filtering.
|
|
15
|
+
*/
|
|
16
|
+
disallowedProcedures?: string[];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Build a tool manifest from a tRPC router by introspecting its procedures
|
|
20
|
+
*
|
|
21
|
+
* @param router - The tRPC router to introspect
|
|
22
|
+
* @param opts - Configuration options
|
|
23
|
+
* @param opts.allowedProcedures - List of procedure paths to include. If omitted, all procedures are included.
|
|
24
|
+
* @param opts.disallowedProcedures - List of procedure paths to exclude. Applied after allowedProcedures.
|
|
25
|
+
* @returns A tool manifest containing definitions for the filtered procedures
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* // Allow all procedures
|
|
30
|
+
* const manifest = buildToolManifest(appRouter);
|
|
31
|
+
*
|
|
32
|
+
* // Only specific procedures
|
|
33
|
+
* const manifest = buildToolManifest(appRouter, {
|
|
34
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"]
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // All except specific procedures
|
|
38
|
+
* const manifest = buildToolManifest(appRouter, {
|
|
39
|
+
* disallowedProcedures: ["admin.deleteUser", "billing.refund"]
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildToolManifest(router: AnyRouter, opts?: BuildToolManifestOptions): ToolManifest;
|
|
44
|
+
//# sourceMappingURL=introspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,cAAc,CAAC;AAGhE,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,2BAA2B,CAAC;AA4B9E;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE,wBAA6B,GAClC,YAAY,CAuCd"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { toJSONSchema } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Extract runtime procedure information from a tRPC router
|
|
4
|
+
*/
|
|
5
|
+
function getRuntimeProcedures(router) {
|
|
6
|
+
const procedures = router._def.procedures;
|
|
7
|
+
return Object.entries(procedures).map(([path, proc]) => {
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
const def = proc._def;
|
|
10
|
+
return {
|
|
11
|
+
path,
|
|
12
|
+
type: def.type,
|
|
13
|
+
inputSchema: def.inputs?.[0],
|
|
14
|
+
outputSchema: def.output ?? undefined,
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build a tool manifest from a tRPC router by introspecting its procedures
|
|
20
|
+
*
|
|
21
|
+
* @param router - The tRPC router to introspect
|
|
22
|
+
* @param opts - Configuration options
|
|
23
|
+
* @param opts.allowedProcedures - List of procedure paths to include. If omitted, all procedures are included.
|
|
24
|
+
* @param opts.disallowedProcedures - List of procedure paths to exclude. Applied after allowedProcedures.
|
|
25
|
+
* @returns A tool manifest containing definitions for the filtered procedures
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* // Allow all procedures
|
|
30
|
+
* const manifest = buildToolManifest(appRouter);
|
|
31
|
+
*
|
|
32
|
+
* // Only specific procedures
|
|
33
|
+
* const manifest = buildToolManifest(appRouter, {
|
|
34
|
+
* allowedProcedures: ["orders.list", "user.updateProfile"]
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // All except specific procedures
|
|
38
|
+
* const manifest = buildToolManifest(appRouter, {
|
|
39
|
+
* disallowedProcedures: ["admin.deleteUser", "billing.refund"]
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function buildToolManifest(router, opts = {}) {
|
|
44
|
+
const { allowedProcedures, disallowedProcedures } = opts;
|
|
45
|
+
const allowedSet = allowedProcedures ? new Set(allowedProcedures) : null;
|
|
46
|
+
const disallowedSet = disallowedProcedures ? new Set(disallowedProcedures) : null;
|
|
47
|
+
const runtimeProcedures = getRuntimeProcedures(router);
|
|
48
|
+
const tools = runtimeProcedures
|
|
49
|
+
.filter((p) => {
|
|
50
|
+
// If allowedProcedures is set, procedure must be in the list
|
|
51
|
+
if (allowedSet && !allowedSet.has(p.path)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
// If disallowedProcedures is set, procedure must not be in the list
|
|
55
|
+
if (disallowedSet && disallowedSet.has(p.path)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
})
|
|
60
|
+
.map((p) => {
|
|
61
|
+
const inputSchema = p.inputSchema
|
|
62
|
+
? toJSONSchema(p.inputSchema, { unrepresentable: "any" })
|
|
63
|
+
: undefined;
|
|
64
|
+
const outputSchema = p.outputSchema
|
|
65
|
+
? toJSONSchema(p.outputSchema, { unrepresentable: "any" })
|
|
66
|
+
: undefined;
|
|
67
|
+
return {
|
|
68
|
+
name: p.path,
|
|
69
|
+
displayName: p.path, // host app can override later if needed
|
|
70
|
+
description: `tRPC procedure ${p.path} (${p.type})`,
|
|
71
|
+
inputSchema,
|
|
72
|
+
outputSchema,
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
tools,
|
|
77
|
+
generated_at: new Date().toISOString(),
|
|
78
|
+
};
|
|
79
|
+
}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM;qBACA,MAAM,SAAS,OAAO,KAAG,IAAI;oBAM9B,MAAM,SAAS,OAAO,KAAG,IAAI;qBAI5B,MAAM,UAAU,OAAO,KAAG,IAAI;CAGhD,CAAC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
3
|
+
export const logger = {
|
|
4
|
+
debug: (message, data) => {
|
|
5
|
+
if (isDev) {
|
|
6
|
+
console.log(`[yak/trpc] ${message}`, data ?? "");
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
warn: (message, data) => {
|
|
10
|
+
console.warn(`[yak/trpc] ${message}`, data ?? "");
|
|
11
|
+
},
|
|
12
|
+
error: (message, error) => {
|
|
13
|
+
console.error(`[yak/trpc] ${message}`, error);
|
|
14
|
+
},
|
|
15
|
+
};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic JSON Schema type
|
|
3
|
+
*/
|
|
4
|
+
export type JSONSchema = Record<string, unknown>;
|
|
5
|
+
/**
|
|
6
|
+
* Payload for a tool call request from the iframe
|
|
7
|
+
*/
|
|
8
|
+
export type ToolCallPayload = {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
args: unknown;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Successful tool call result
|
|
15
|
+
*/
|
|
16
|
+
export type ToolCallSuccess = {
|
|
17
|
+
ok: true;
|
|
18
|
+
result: unknown;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Failed tool call result
|
|
22
|
+
*/
|
|
23
|
+
export type ToolCallError = {
|
|
24
|
+
ok: false;
|
|
25
|
+
error: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Union type for tool call responses
|
|
29
|
+
*/
|
|
30
|
+
export type ToolCallResult = ToolCallSuccess | ToolCallError;
|
|
31
|
+
/**
|
|
32
|
+
* Definition of a single tool (tRPC procedure) available to the LLM
|
|
33
|
+
*/
|
|
34
|
+
export type ToolDefinition = {
|
|
35
|
+
/** Fully qualified procedure name, e.g. "orders.list" */
|
|
36
|
+
name: string;
|
|
37
|
+
/** Human friendly label */
|
|
38
|
+
displayName?: string;
|
|
39
|
+
/** Description shown to the LLM as a tool description */
|
|
40
|
+
description?: string;
|
|
41
|
+
/** Optional JSON Schema for input args */
|
|
42
|
+
inputSchema?: JSONSchema;
|
|
43
|
+
/** Optional JSON Schema for output shape (not required in v1) */
|
|
44
|
+
outputSchema?: JSONSchema;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A manifest of available tools exposed to the chatbot
|
|
48
|
+
*/
|
|
49
|
+
export type ToolManifest = {
|
|
50
|
+
tools: ToolDefinition[];
|
|
51
|
+
generated_at: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Information about a Next.js route
|
|
55
|
+
*/
|
|
56
|
+
export type RouteInfo = {
|
|
57
|
+
path: string;
|
|
58
|
+
/** Human-readable title extracted from page metadata */
|
|
59
|
+
title?: string;
|
|
60
|
+
/** Description extracted from page metadata */
|
|
61
|
+
description?: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* A manifest of available routes in the Next.js application
|
|
65
|
+
*/
|
|
66
|
+
export type RouteManifest = {
|
|
67
|
+
routes: RouteInfo[];
|
|
68
|
+
generated_at: string;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Combined configuration for the chatbot including tools and routes
|
|
72
|
+
*/
|
|
73
|
+
export type ChatConfig = {
|
|
74
|
+
tools: ToolManifest;
|
|
75
|
+
routes: RouteManifest;
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,aAAa,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IAEb,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,UAAU,CAAC;IAEzB,iEAAiE;IACjE,YAAY,CAAC,EAAE,UAAU,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yak-io/trpc",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "tRPC adapter for yak chatbot - enables tRPC procedures as chatbot tools",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
7
|
+
"author": "Yak <support@yak.io>",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/9f-au/yak.git",
|
|
11
|
+
"directory": "packages/trpc"
|
|
12
|
+
},
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public",
|
|
15
|
+
"provenance": false
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"yak",
|
|
19
|
+
"chatbot",
|
|
20
|
+
"ai",
|
|
21
|
+
"trpc",
|
|
22
|
+
"tools"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"import": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./package.json": "./package.json"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@yak-io/javascript": "0.1.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@trpc/server": "^10.0.0 || ^11.0.0",
|
|
44
|
+
"zod": "^4.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@trpc/server": "^11.8.0",
|
|
48
|
+
"@types/node": "^24.10.2",
|
|
49
|
+
"typescript": "^5.3.0",
|
|
50
|
+
"zod": "^4.1.13",
|
|
51
|
+
"@repo/typescript-config": "0.0.0"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc",
|
|
55
|
+
"check-types": "tsc --noEmit"
|
|
56
|
+
}
|
|
57
|
+
}
|