@fragno-dev/chatno 0.0.16 → 0.0.18
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/CHANGELOG.md +18 -0
- package/package.json +10 -3
- package/src/client/react.ts +1 -1
- package/src/client/solid.ts +1 -1
- package/src/client/svelte.ts +1 -1
- package/src/client/vanilla.ts +1 -1
- package/src/client/vue.ts +1 -1
- package/src/index.test.ts +23 -23
- package/src/index.ts +27 -36
- package/src/server/chatno-api.ts +7 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @fragno-dev/chatno
|
|
2
2
|
|
|
3
|
+
## 0.0.18
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [aabd6d2]
|
|
8
|
+
- @fragno-dev/core@0.1.10
|
|
9
|
+
|
|
10
|
+
## 0.0.17
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 5ea24d2: refactor: improve Fragment builder and instatiator
|
|
15
|
+
- Updated dependencies [e848208]
|
|
16
|
+
- Updated dependencies [7276378]
|
|
17
|
+
- Updated dependencies [5ea24d2]
|
|
18
|
+
- Updated dependencies [f22c503]
|
|
19
|
+
- @fragno-dev/core@0.1.9
|
|
20
|
+
|
|
3
21
|
## 0.0.16
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fragno-dev/chatno",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"development": {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"nanostores": "^1.0.1",
|
|
59
59
|
"openai": "^5.20.0",
|
|
60
60
|
"zod": "^4.0.5",
|
|
61
|
-
"@fragno-dev/core": "0.1.
|
|
61
|
+
"@fragno-dev/core": "0.1.10"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"typescript": "^5.9.3",
|
|
@@ -70,8 +70,15 @@
|
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^22",
|
|
72
72
|
"@fragno-private/typescript-config": "0.0.1",
|
|
73
|
-
"@fragno-dev/unplugin-fragno": "0.0.
|
|
73
|
+
"@fragno-dev/unplugin-fragno": "0.0.6"
|
|
74
74
|
},
|
|
75
|
+
"repository": {
|
|
76
|
+
"type": "git",
|
|
77
|
+
"url": "https://github.com/rejot-dev/fragno.git",
|
|
78
|
+
"directory": "example-fragments/chatno"
|
|
79
|
+
},
|
|
80
|
+
"homepage": "https://fragno.dev",
|
|
81
|
+
"license": "MIT",
|
|
75
82
|
"scripts": {
|
|
76
83
|
"build": "tsdown",
|
|
77
84
|
"build:watch": "tsdown --watch",
|
package/src/client/react.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useFragno } from "@fragno-dev/core/react";
|
|
2
2
|
import { createChatnoClients } from "..";
|
|
3
|
-
import type { FragnoPublicClientConfig } from "@fragno-dev/core";
|
|
3
|
+
import type { FragnoPublicClientConfig } from "@fragno-dev/core/client";
|
|
4
4
|
|
|
5
5
|
export function createChatnoClient(config: FragnoPublicClientConfig = {}) {
|
|
6
6
|
return useFragno(createChatnoClients(config));
|
package/src/client/solid.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useFragno } from "@fragno-dev/core/solid";
|
|
2
2
|
import { createChatnoClients } from "..";
|
|
3
|
-
import type { FragnoPublicClientConfig } from "@fragno-dev/core";
|
|
3
|
+
import type { FragnoPublicClientConfig } from "@fragno-dev/core/client";
|
|
4
4
|
|
|
5
5
|
export function createChatnoClient(config: FragnoPublicClientConfig = {}) {
|
|
6
6
|
return useFragno(createChatnoClients(config));
|
package/src/client/svelte.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useFragno } from "@fragno-dev/core/svelte";
|
|
2
2
|
import { createChatnoClients } from "..";
|
|
3
|
-
import type { FragnoPublicClientConfig } from "@fragno-dev/core";
|
|
3
|
+
import type { FragnoPublicClientConfig } from "@fragno-dev/core/client";
|
|
4
4
|
|
|
5
5
|
export function createChatnoClient(config: FragnoPublicClientConfig = {}) {
|
|
6
6
|
return useFragno(createChatnoClients(config));
|
package/src/client/vanilla.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useFragno } from "@fragno-dev/core/vanilla";
|
|
2
2
|
import { createChatnoClients } from "..";
|
|
3
|
-
import type { FragnoPublicClientConfig } from "@fragno-dev/core";
|
|
3
|
+
import type { FragnoPublicClientConfig } from "@fragno-dev/core/client";
|
|
4
4
|
|
|
5
5
|
export function createChatnoClient(config: FragnoPublicClientConfig = {}) {
|
|
6
6
|
return useFragno(createChatnoClients(config));
|
package/src/client/vue.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useFragno } from "@fragno-dev/core/vue";
|
|
2
2
|
import { createChatnoClients } from "..";
|
|
3
|
-
import type { FragnoPublicClientConfig } from "@fragno-dev/core";
|
|
3
|
+
import type { FragnoPublicClientConfig } from "@fragno-dev/core/client";
|
|
4
4
|
|
|
5
5
|
export function createChatnoClient(config: FragnoPublicClientConfig = {}) {
|
|
6
6
|
return useFragno(createChatnoClients(config));
|
package/src/index.test.ts
CHANGED
|
@@ -1,34 +1,21 @@
|
|
|
1
1
|
import { describe, it, expect, assert } from "vitest";
|
|
2
2
|
import { createFragmentForTest } from "@fragno-dev/core/test";
|
|
3
|
-
import { chatnoDefinition,
|
|
4
|
-
import { chatRouteFactory } from "./server/chatno-api";
|
|
3
|
+
import { chatnoDefinition, routes } from "./index";
|
|
5
4
|
|
|
6
5
|
describe("chatno", () => {
|
|
7
|
-
const routes = [chatRouteFactory, healthRoute, simpleStreamRoute] as const;
|
|
8
6
|
const fragment = createFragmentForTest(chatnoDefinition, routes, {
|
|
9
7
|
config: {
|
|
10
8
|
openaiApiKey: "test-key",
|
|
11
9
|
},
|
|
12
10
|
});
|
|
13
11
|
|
|
14
|
-
// Test with just
|
|
15
|
-
const
|
|
12
|
+
// Test with just the factory (which includes both health and simple-stream routes)
|
|
13
|
+
const fragmentJustFactory = createFragmentForTest(chatnoDefinition, [routes[1]!] as const, {
|
|
16
14
|
config: {
|
|
17
15
|
openaiApiKey: "test-key",
|
|
18
16
|
},
|
|
19
17
|
});
|
|
20
18
|
|
|
21
|
-
// Test with just a factory
|
|
22
|
-
const fragmentJustFactory = createFragmentForTest(
|
|
23
|
-
chatnoDefinition,
|
|
24
|
-
[simpleStreamRoute] as const,
|
|
25
|
-
{
|
|
26
|
-
config: {
|
|
27
|
-
openaiApiKey: "test-key",
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
);
|
|
31
|
-
|
|
32
19
|
it("services - should return OpenAI URL from getOpenAIURL service", () => {
|
|
33
20
|
const openaiURL = fragment.services.getOpenAIURL();
|
|
34
21
|
|
|
@@ -82,18 +69,31 @@ describe("chatno", () => {
|
|
|
82
69
|
expect(response.data).toEqual({ status: "ok" });
|
|
83
70
|
});
|
|
84
71
|
|
|
85
|
-
it("routes - should test
|
|
86
|
-
const response = await
|
|
72
|
+
it("routes - should test simple stream with factory fragment", async () => {
|
|
73
|
+
const response = await fragmentJustFactory.callRoute("GET", "/simple-stream");
|
|
87
74
|
|
|
88
|
-
assert(response.type === "
|
|
75
|
+
assert(response.type === "jsonStream");
|
|
89
76
|
expect(response.status).toBe(200);
|
|
90
|
-
|
|
77
|
+
const data = await Array.fromAsync(response.stream);
|
|
78
|
+
expect(data).toEqual([
|
|
79
|
+
{ message: "Item 1" },
|
|
80
|
+
{ message: "Item 2" },
|
|
81
|
+
{ message: "Item 3" },
|
|
82
|
+
{ message: "Item 4" },
|
|
83
|
+
{ message: "Item 5" },
|
|
84
|
+
{ message: "Item 6" },
|
|
85
|
+
{ message: "Item 7" },
|
|
86
|
+
{ message: "Item 8" },
|
|
87
|
+
{ message: "Item 9" },
|
|
88
|
+
{ message: "Item 10" },
|
|
89
|
+
]);
|
|
91
90
|
});
|
|
92
91
|
|
|
93
|
-
it("routes - should test
|
|
94
|
-
const response = await fragmentJustFactory.callRoute("GET", "/
|
|
92
|
+
it("routes - should test health route with factory fragment", async () => {
|
|
93
|
+
const response = await fragmentJustFactory.callRoute("GET", "/health");
|
|
95
94
|
|
|
96
|
-
assert(response.type === "
|
|
95
|
+
assert(response.type === "json");
|
|
97
96
|
expect(response.status).toBe(200);
|
|
97
|
+
expect(response.data).toEqual({ status: "ok" });
|
|
98
98
|
});
|
|
99
99
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defineFragment,
|
|
3
|
-
|
|
4
|
-
createFragment,
|
|
5
|
-
type FragnoPublicClientConfig,
|
|
6
|
-
type FragnoPublicConfig,
|
|
3
|
+
instantiate,
|
|
7
4
|
defineRoutes,
|
|
5
|
+
type FragnoPublicConfig,
|
|
8
6
|
} from "@fragno-dev/core";
|
|
7
|
+
import type { FragnoPublicClientConfig } from "@fragno-dev/core/client";
|
|
8
|
+
import { createClientBuilder } from "@fragno-dev/core/client";
|
|
9
9
|
import OpenAI from "openai";
|
|
10
10
|
import { z } from "zod";
|
|
11
|
-
import { createClientBuilder } from "@fragno-dev/core/client";
|
|
12
11
|
import { chatRouteFactory } from "./server/chatno-api";
|
|
13
12
|
import { computed } from "nanostores";
|
|
14
13
|
|
|
@@ -18,23 +17,6 @@ export interface ChatnoServerConfig {
|
|
|
18
17
|
systemPrompt?: string;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
const healthRoute = defineRoute({
|
|
22
|
-
method: "GET",
|
|
23
|
-
path: "/health",
|
|
24
|
-
outputSchema: z.object({
|
|
25
|
-
status: z.literal("ok"),
|
|
26
|
-
}),
|
|
27
|
-
handler: async (_ctx, { json }) => {
|
|
28
|
-
return json({ status: "ok" });
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
const DEFAULT_SYSTEM_PROMPT = `You are an AI assistant integrated into a dashboard.`;
|
|
33
|
-
|
|
34
|
-
interface SimpleStreamService {
|
|
35
|
-
generateStreamMessages: () => AsyncGenerator<{ message: string }>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
20
|
export const chatnoDefinition = defineFragment<ChatnoServerConfig>("chatno")
|
|
39
21
|
.withDependencies(({ config }) => {
|
|
40
22
|
return {
|
|
@@ -43,8 +25,8 @@ export const chatnoDefinition = defineFragment<ChatnoServerConfig>("chatno")
|
|
|
43
25
|
}),
|
|
44
26
|
};
|
|
45
27
|
})
|
|
46
|
-
.
|
|
47
|
-
return
|
|
28
|
+
.providesBaseService(({ deps }) => {
|
|
29
|
+
return {
|
|
48
30
|
getOpenAIURL: () => deps.openaiClient.baseURL,
|
|
49
31
|
generateStreamMessages: async function* () {
|
|
50
32
|
for (let i = 0; i < 10; i++) {
|
|
@@ -52,12 +34,23 @@ export const chatnoDefinition = defineFragment<ChatnoServerConfig>("chatno")
|
|
|
52
34
|
yield { message: `Item ${i + 1}` };
|
|
53
35
|
}
|
|
54
36
|
},
|
|
55
|
-
}
|
|
56
|
-
})
|
|
37
|
+
};
|
|
38
|
+
})
|
|
39
|
+
.build();
|
|
57
40
|
|
|
58
|
-
const
|
|
59
|
-
({ services }) => {
|
|
41
|
+
const healthAndStreamRoutesFactory = defineRoutes(chatnoDefinition).create(
|
|
42
|
+
({ defineRoute, services }) => {
|
|
60
43
|
return [
|
|
44
|
+
defineRoute({
|
|
45
|
+
method: "GET",
|
|
46
|
+
path: "/health",
|
|
47
|
+
outputSchema: z.object({
|
|
48
|
+
status: z.literal("ok"),
|
|
49
|
+
}),
|
|
50
|
+
handler: async (_ctx, { json }) => {
|
|
51
|
+
return json({ status: "ok" });
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
61
54
|
defineRoute({
|
|
62
55
|
method: "GET",
|
|
63
56
|
path: "/simple-stream",
|
|
@@ -78,20 +71,18 @@ const simpleStreamRoute = defineRoutes<ChatnoServerConfig, {}, SimpleStreamServi
|
|
|
78
71
|
},
|
|
79
72
|
);
|
|
80
73
|
|
|
81
|
-
export
|
|
82
|
-
export const routes = [chatRouteFactory, healthRoute, simpleStreamRoute] as const;
|
|
74
|
+
export const routes = [chatRouteFactory, healthAndStreamRoutesFactory] as const;
|
|
83
75
|
|
|
84
76
|
// Server-side factory
|
|
85
77
|
export function createChatno(
|
|
86
78
|
chatnoConfig: ChatnoServerConfig,
|
|
87
79
|
fragnoConfig: FragnoPublicConfig = {},
|
|
88
80
|
) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return createFragment(chatnoDefinition, { ...chatnoConfig, ...config }, routes, fragnoConfig);
|
|
81
|
+
return instantiate(chatnoDefinition)
|
|
82
|
+
.withConfig(chatnoConfig)
|
|
83
|
+
.withRoutes(routes)
|
|
84
|
+
.withOptions(fragnoConfig)
|
|
85
|
+
.build();
|
|
95
86
|
}
|
|
96
87
|
|
|
97
88
|
// Generic client-side factory
|
package/src/server/chatno-api.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import OpenAI from "openai";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import type {
|
|
4
3
|
EasyInputMessage,
|
|
5
4
|
ResponseFunctionToolCall,
|
|
6
5
|
ResponseInputItem,
|
|
7
6
|
} from "openai/resources/responses/responses.mjs";
|
|
8
|
-
import {
|
|
7
|
+
import type { chatnoDefinition } from "../index";
|
|
8
|
+
import { defineRoutes } from "@fragno-dev/core";
|
|
9
9
|
|
|
10
10
|
export const ChatMessageSchema = z.object({
|
|
11
11
|
type: z.literal("chat"),
|
|
@@ -64,19 +64,13 @@ export const ResponseEventSchema = z.discriminatedUnion("type", [
|
|
|
64
64
|
ResponseTextDoneEventSchema,
|
|
65
65
|
]);
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
model: "gpt-5-mini" | "4o-mini";
|
|
69
|
-
systemPrompt: string;
|
|
70
|
-
};
|
|
67
|
+
const DEFAULT_SYSTEM_PROMPT = `You are an AI assistant integrated into a dashboard.`;
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export const chatRouteFactory = defineRoutes<ChatRouteConfig, ChatRouteDeps>().create(
|
|
77
|
-
({ config, deps }) => {
|
|
69
|
+
// Export function to create the chat route factory with the definition
|
|
70
|
+
export const chatRouteFactory = defineRoutes<typeof chatnoDefinition>().create(
|
|
71
|
+
({ config, deps, defineRoute }) => {
|
|
78
72
|
const { openaiClient } = deps;
|
|
79
|
-
const { model, systemPrompt } = config;
|
|
73
|
+
const { model = "gpt-5-nano", systemPrompt = DEFAULT_SYSTEM_PROMPT } = config;
|
|
80
74
|
|
|
81
75
|
return [
|
|
82
76
|
defineRoute({
|