@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 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.16",
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.8"
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.3"
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",
@@ -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));
@@ -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));
@@ -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));
@@ -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, healthRoute, simpleStreamRoute } from "./index";
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 healthRoute
15
- const fragmentJustHealth = createFragmentForTest(chatnoDefinition, [healthRoute] as 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 health route with simple fragment", async () => {
86
- const response = await fragmentJustHealth.callRoute("GET", "/health");
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 === "json");
75
+ assert(response.type === "jsonStream");
89
76
  expect(response.status).toBe(200);
90
- expect(response.data).toEqual({ status: "ok" });
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 simple stream with factory fragment", async () => {
94
- const response = await fragmentJustFactory.callRoute("GET", "/simple-stream");
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 === "jsonStream");
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
- defineRoute,
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
- .providesService(({ deps, defineService }) => {
47
- return defineService({
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 simpleStreamRoute = defineRoutes<ChatnoServerConfig, {}, SimpleStreamService>().create(
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 { healthRoute, simpleStreamRoute };
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
- const config = {
90
- model: chatnoConfig.model ?? "gpt-5-nano",
91
- systemPrompt: chatnoConfig.systemPrompt ?? DEFAULT_SYSTEM_PROMPT,
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
@@ -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 { defineRoute, defineRoutes } from "@fragno-dev/core";
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
- type ChatRouteConfig = {
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
- type ChatRouteDeps = {
73
- openaiClient: OpenAI;
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({