@falai/agent 0.6.4 → 0.6.6

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.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/core/Agent.d.ts.map +1 -1
  3. package/dist/cjs/core/Agent.js +7 -7
  4. package/dist/cjs/core/Agent.js.map +1 -1
  5. package/dist/cjs/core/ResponseEngine.d.ts +1 -1
  6. package/dist/cjs/core/ResponseEngine.d.ts.map +1 -1
  7. package/dist/cjs/core/ResponseEngine.js +4 -1
  8. package/dist/cjs/core/ResponseEngine.js.map +1 -1
  9. package/dist/cjs/core/RoutingEngine.js +4 -4
  10. package/dist/cjs/core/RoutingEngine.js.map +1 -1
  11. package/dist/cjs/core/State.d.ts +3 -1
  12. package/dist/cjs/core/State.d.ts.map +1 -1
  13. package/dist/cjs/core/State.js +6 -2
  14. package/dist/cjs/core/State.js.map +1 -1
  15. package/dist/cjs/types/session.d.ts +2 -2
  16. package/dist/cjs/types/session.d.ts.map +1 -1
  17. package/dist/cjs/types/session.js +3 -1
  18. package/dist/cjs/types/session.js.map +1 -1
  19. package/dist/core/Agent.d.ts.map +1 -1
  20. package/dist/core/Agent.js +7 -7
  21. package/dist/core/Agent.js.map +1 -1
  22. package/dist/core/ResponseEngine.d.ts +1 -1
  23. package/dist/core/ResponseEngine.d.ts.map +1 -1
  24. package/dist/core/ResponseEngine.js +4 -1
  25. package/dist/core/ResponseEngine.js.map +1 -1
  26. package/dist/core/RoutingEngine.js +4 -4
  27. package/dist/core/RoutingEngine.js.map +1 -1
  28. package/dist/core/State.d.ts +3 -1
  29. package/dist/core/State.d.ts.map +1 -1
  30. package/dist/core/State.js +6 -2
  31. package/dist/core/State.js.map +1 -1
  32. package/dist/types/session.d.ts +2 -2
  33. package/dist/types/session.d.ts.map +1 -1
  34. package/dist/types/session.js +3 -1
  35. package/dist/types/session.js.map +1 -1
  36. package/docs/ARCHITECTURE.md +1 -1
  37. package/docs/CONTRIBUTING.md +3 -3
  38. package/docs/DOCS.md +4 -4
  39. package/docs/EXAMPLES.md +21 -22
  40. package/docs/PUBLISHING.md +15 -3
  41. package/examples/travel-agent.ts +1 -1
  42. package/package.json +4 -4
  43. package/src/core/Agent.ts +7 -5
  44. package/src/core/ResponseEngine.ts +6 -0
  45. package/src/core/RoutingEngine.ts +4 -4
  46. package/src/core/State.ts +10 -2
  47. package/src/types/session.ts +7 -3
@@ -3,6 +3,7 @@
3
3
  ## Pre-publish Checklist
4
4
 
5
5
  ### 1. Build and Test
6
+
6
7
  ```bash
7
8
  # Clean previous builds
8
9
  rm -rf dist/
@@ -22,13 +23,15 @@ npm pack
22
23
  ### 2. Version Management
23
24
 
24
25
  Update version in `package.json`:
26
+
25
27
  ```json
26
28
  {
27
- "version": "0.1.0" // Follow semver: major.minor.patch
29
+ "version": "0.1.0" // Follow semver: major.minor.patch
28
30
  }
29
31
  ```
30
32
 
31
33
  **Semver Guidelines:**
34
+
32
35
  - **Patch** (0.1.X): Bug fixes, documentation updates
33
36
  - **Minor** (0.X.0): New features, backwards compatible
34
37
  - **Major** (X.0.0): Breaking changes
@@ -44,6 +47,7 @@ npm pack --dry-run
44
47
  ```
45
48
 
46
49
  Should include:
50
+
47
51
  - ✅ `dist/` - Compiled JavaScript + type definitions
48
52
  - ✅ `docs/` - Documentation
49
53
  - ✅ `examples/` - Example files
@@ -51,6 +55,7 @@ Should include:
51
55
  - ✅ `LICENSE` - MIT license
52
56
 
53
57
  Should NOT include:
58
+
54
59
  - ❌ `src/*.ts` source files (only .d.ts)
55
60
  - ❌ `node_modules/`
56
61
  - ❌ Development configs
@@ -99,11 +104,13 @@ npm view @falai/agent
99
104
  ## Post-Publish
100
105
 
101
106
  1. **Update GitHub Release**
102
- - Go to https://github.com/gusnips/falai/releases
107
+
108
+ - Go to https://github.com/falai-dev/agent/releases
103
109
  - Create a new release for the tag
104
110
  - Add release notes
105
111
 
106
112
  2. **Verify Installation**
113
+
107
114
  ```bash
108
115
  # In a new project
109
116
  npm install @falai/agent
@@ -112,12 +119,13 @@ npm view @falai/agent
112
119
  ```
113
120
 
114
121
  3. **Test the Published Package**
122
+
115
123
  ```bash
116
124
  # Create test project
117
125
  mkdir test-agent && cd test-agent
118
126
  bun init -y
119
127
  bun add @falai/agent
120
-
128
+
121
129
  # Try importing
122
130
  echo 'import { Agent } from "@falai/agent"; console.log(Agent);' > test.ts
123
131
  bun run test.ts
@@ -126,20 +134,24 @@ npm view @falai/agent
126
134
  ## Troubleshooting
127
135
 
128
136
  ### "You do not have permission to publish"
137
+
129
138
  - Make sure you're logged in: `npm whoami`
130
139
  - Verify you have access to the `@falai` scope
131
140
  - Contact scope owner if needed
132
141
 
133
142
  ### "Package already exists"
143
+
134
144
  - You can't republish the same version
135
145
  - Bump version in `package.json` and try again
136
146
 
137
147
  ### "Missing required files"
148
+
138
149
  - Check `package.json` `files` field
139
150
  - Ensure `dist/` exists after build
140
151
  - Run `npm pack --dry-run` to preview
141
152
 
142
153
  ### Types not working
154
+
143
155
  - Verify `types` field in `package.json`
144
156
  - Ensure `.d.ts` files are in `dist/`
145
157
  - Check `tsconfig.json` has `"declaration": true`
@@ -182,7 +182,7 @@ async function createTravelAgent() {
182
182
  apiKey: process.env.OPENROUTER_API_KEY || "test-key",
183
183
  model: "google/gemini-2.0-flash-exp",
184
184
  backupModels: ["anthropic/claude-sonnet-4-5", "openai/gpt-5"],
185
- siteUrl: "https://github.com/gusnips/falai",
185
+ siteUrl: "https://github.com/falai-dev/agent",
186
186
  siteName: "Falai Travel Agent Example",
187
187
  retryConfig: {
188
188
  timeout: 60000,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@falai/agent",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
4
4
  "description": "Standalone, strongly-typed AI Agent framework with route DSL and AI provider strategy",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -31,12 +31,12 @@
31
31
  },
32
32
  "repository": {
33
33
  "type": "git",
34
- "url": "https://github.com/gusnips/falai.git"
34
+ "url": "https://github.com/falai-dev/agent.git"
35
35
  },
36
36
  "bugs": {
37
- "url": "https://github.com/gusnips/falai/issues"
37
+ "url": "https://github.com/falai-dev/agent/issues"
38
38
  },
39
- "homepage": "https://github.com/gusnips/falai#readme",
39
+ "homepage": "https://github.com/falai-dev/agent#readme",
40
40
  "scripts": {
41
41
  "build": "npm run build:esm && npm run build:cjs && npm run fix:cjs",
42
42
  "build:esm": "tsc",
package/src/core/Agent.ts CHANGED
@@ -405,7 +405,7 @@ export class Agent<TContext = unknown> {
405
405
  const candidates = this.routingEngine.getCandidateStates(
406
406
  selectedRoute,
407
407
  undefined,
408
- session.extracted
408
+ session.extracted || {}
409
409
  );
410
410
  if (candidates.length > 0) {
411
411
  nextState = candidates[0].state;
@@ -438,6 +438,7 @@ export class Agent<TContext = unknown> {
438
438
  // Build response prompt
439
439
  const responsePrompt = this.responseEngine.buildResponsePrompt(
440
440
  selectedRoute,
441
+ nextState,
441
442
  selectedRoute.getRules(),
442
443
  selectedRoute.getProhibitions(),
443
444
  responseDirectives,
@@ -735,7 +736,7 @@ export class Agent<TContext = unknown> {
735
736
  const candidates = this.routingEngine.getCandidateStates(
736
737
  selectedRoute,
737
738
  undefined,
738
- session.extracted
739
+ session.extracted || {}
739
740
  );
740
741
  if (candidates.length > 0) {
741
742
  nextState = candidates[0].state;
@@ -768,6 +769,7 @@ export class Agent<TContext = unknown> {
768
769
  // Build response prompt
769
770
  const responsePrompt = this.responseEngine.buildResponsePrompt(
770
771
  selectedRoute,
772
+ nextState,
771
773
  selectedRoute.getRules(),
772
774
  selectedRoute.getProhibitions(),
773
775
  responseDirectives,
@@ -810,7 +812,7 @@ export class Agent<TContext = unknown> {
810
812
 
811
813
  // Merge gathered data into session
812
814
  if (Object.keys(gatheredData).length > 0) {
813
- session = mergeExtracted(session, gatheredData);
815
+ session = await this.updateExtracted(session, gatheredData);
814
816
  logger.debug(`[Agent] Extracted data:`, gatheredData);
815
817
  }
816
818
  }
@@ -1014,11 +1016,11 @@ export class Agent<TContext = unknown> {
1014
1016
  }
1015
1017
  if (routeId) {
1016
1018
  return (
1017
- (this.currentSession.extractedByRoute[
1019
+ (this.currentSession.extractedByRoute?.[
1018
1020
  routeId
1019
1021
  ] as Partial<TExtracted>) || ({} as Partial<TExtracted>)
1020
1022
  );
1021
1023
  }
1022
- return this.currentSession.extracted as Partial<TExtracted>;
1024
+ return (this.currentSession.extracted as Partial<TExtracted>) || {};
1023
1025
  }
1024
1026
  }
@@ -44,6 +44,7 @@ export class ResponseEngine<TContext = unknown> {
44
44
 
45
45
  buildResponsePrompt(
46
46
  route: Route<TContext>,
47
+ currentState: State<TContext>,
47
48
  rules: string[],
48
49
  prohibitions: string[],
49
50
  directives: string[] | undefined,
@@ -71,6 +72,11 @@ export class ResponseEngine<TContext = unknown> {
71
72
  route.description ? ` — ${route.description}` : ""
72
73
  }`
73
74
  );
75
+ if (currentState.chatState) {
76
+ pc.addInstruction(
77
+ `Guideline for your response (adapt to the conversation):\n${currentState.chatState}`
78
+ );
79
+ }
74
80
  if (rules.length) pc.addInstruction(`Rules:\n- ${rules.join("\n- ")}`);
75
81
  if (prohibitions.length)
76
82
  pc.addInstruction(`Prohibitions:\n- ${prohibitions.join("\n- ")}`);
@@ -87,7 +87,7 @@ export class RoutingEngine<TContext = unknown> {
87
87
  const candidates = this.getCandidateStates(
88
88
  route,
89
89
  currentState,
90
- updatedSession.extracted
90
+ updatedSession.extracted || {}
91
91
  );
92
92
 
93
93
  if (candidates.length === 0) {
@@ -128,7 +128,7 @@ export class RoutingEngine<TContext = unknown> {
128
128
  route,
129
129
  currentState,
130
130
  candidates,
131
- updatedSession.extracted,
131
+ updatedSession.extracted || {},
132
132
  history,
133
133
  lastUserMessage,
134
134
  agentMeta
@@ -465,7 +465,7 @@ export class RoutingEngine<TContext = unknown> {
465
465
  const candidates = this.getCandidateStates(
466
466
  activeRoute,
467
467
  currentState,
468
- session.extracted
468
+ session.extracted || {}
469
469
  );
470
470
 
471
471
  // Check if route is complete
@@ -857,7 +857,7 @@ export class RoutingEngine<TContext = unknown> {
857
857
  sessionInfo.push(` "${session.currentState.description}"`);
858
858
  }
859
859
  }
860
- if (Object.keys(session.extracted).length > 0) {
860
+ if (session.extracted && Object.keys(session.extracted).length > 0) {
861
861
  sessionInfo.push(
862
862
  `- Extracted data: ${JSON.stringify(session.extracted)}`
863
863
  );
package/src/core/State.ts CHANGED
@@ -23,6 +23,7 @@ export class State<TContext = unknown, TExtracted = unknown> {
23
23
  public gatherFields?: string[];
24
24
  public skipIf?: (extracted: Partial<TExtracted>) => boolean;
25
25
  public requiredData?: string[];
26
+ public chatState?: string;
26
27
 
27
28
  constructor(
28
29
  public readonly routeId: string,
@@ -30,13 +31,15 @@ export class State<TContext = unknown, TExtracted = unknown> {
30
31
  customId?: string,
31
32
  gatherFields?: string[],
32
33
  skipIf?: (extracted: Partial<TExtracted>) => boolean,
33
- requiredData?: string[]
34
+ requiredData?: string[],
35
+ chatState?: string
34
36
  ) {
35
37
  // Use provided ID or generate a deterministic one
36
38
  this.id = customId || generateStateId(routeId, description);
37
39
  this.gatherFields = gatherFields;
38
40
  this.skipIf = skipIf;
39
41
  this.requiredData = requiredData;
42
+ this.chatState = chatState;
40
43
  }
41
44
 
42
45
  /**
@@ -48,6 +51,7 @@ export class State<TContext = unknown, TExtracted = unknown> {
48
51
  gatherFields?: string[];
49
52
  skipIf?: (extracted: Partial<TExtracted>) => boolean;
50
53
  requiredData?: string[];
54
+ chatState?: string;
51
55
  }): this {
52
56
  if (config.description !== undefined) {
53
57
  this.description = config.description;
@@ -61,6 +65,9 @@ export class State<TContext = unknown, TExtracted = unknown> {
61
65
  if (config.requiredData !== undefined) {
62
66
  this.requiredData = config.requiredData;
63
67
  }
68
+ if (config.chatState !== undefined) {
69
+ this.chatState = config.chatState;
70
+ }
64
71
  return this;
65
72
  }
66
73
 
@@ -107,7 +114,8 @@ export class State<TContext = unknown, TExtracted = unknown> {
107
114
  spec.id, // Use custom ID if provided
108
115
  spec.gather,
109
116
  spec.skipIf,
110
- spec.requiredData
117
+ spec.requiredData,
118
+ spec.chatState
111
119
  );
112
120
  const transition = new Transition<TContext, TExtracted>(
113
121
  this.getRef(),
@@ -28,14 +28,14 @@ export interface SessionState<TExtracted = Record<string, unknown>> {
28
28
  * Data extracted during the current route
29
29
  * This is a convenience reference to extractedByRoute[currentRoute.id]
30
30
  */
31
- extracted: Partial<TExtracted>;
31
+ extracted?: Partial<TExtracted>;
32
32
 
33
33
  /**
34
34
  * Extracted data organized by route ID
35
35
  * Preserves data when switching between routes
36
36
  * Format: { "routeId": { ...extractedData } }
37
37
  */
38
- extractedByRoute: Record<string, Partial<unknown>>;
38
+ extractedByRoute?: Record<string, Partial<unknown>>;
39
39
 
40
40
  /** History of routes visited in this session */
41
41
  routeHistory: Array<{
@@ -86,7 +86,11 @@ export function enterRoute<TExtracted = Record<string, unknown>>(
86
86
  ): SessionState<TExtracted> {
87
87
  // Save current route's extracted data before switching
88
88
  const extractedByRoute = { ...session.extractedByRoute };
89
- if (session.currentRoute && Object.keys(session.extracted).length > 0) {
89
+ if (
90
+ session.currentRoute &&
91
+ session.extracted &&
92
+ Object.keys(session.extracted).length > 0
93
+ ) {
90
94
  extractedByRoute[session.currentRoute.id] = session.extracted;
91
95
  }
92
96