motia 0.6.4-beta.131-211436 → 0.6.4-beta.131-014082

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.
@@ -33,4 +33,10 @@ describe('extractPythonData', () => {
33
33
  const requirements = (0, read_requirements_1.readRequirements)(path_1.default.join(rootDir, 'requirements.txt'), mockPackageDescriber);
34
34
  expect(() => (0, extract_python_data_1.extractPythonData)(rootDir, `/steps/api_step.py`, requirements)).toThrow(new python_errors_1.PythonError("Compilation error: no viable alternative at input ':' at line 3:10 in /steps/api_step.py", '/steps/api_step.py'));
35
35
  });
36
+ test('extracts python data with nested import from requirements', () => {
37
+ const rootDir = path_1.default.join(__dirname, './examples/chessarena');
38
+ const requirements = (0, read_requirements_1.readRequirements)(path_1.default.join(rootDir, 'requirements.txt'), mockPackageDescriber);
39
+ const result = (0, extract_python_data_1.extractPythonData)(rootDir, `/steps/evaluate_player_move_step.py`, requirements);
40
+ expect(result.externalDependencies).toEqual({ chess: 'chess>=1.0.0', pydantic: 'pydantic>=2.6.1' });
41
+ });
36
42
  });
@@ -53,13 +53,14 @@ const getDependenciesFromFile = (content, path, requirements) => {
53
53
  projectDependencies: new Set(),
54
54
  };
55
55
  for (const module of modulesSet) {
56
+ const [moduleName] = module.split('.');
56
57
  if (module[0] === '.') {
57
58
  dependencies.projectDependencies.add(module);
58
59
  }
59
60
  else if (constants_1.STANDARD_LIB_MODULES.has(module)) {
60
61
  dependencies.standardLibDependencies.add(module);
61
62
  }
62
- else if (requirements[module]) {
63
+ else if (requirements[module] || requirements[moduleName]) {
63
64
  dependencies.externalDependencies.add(module);
64
65
  }
65
66
  else {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateLockedData = exports.collectFlows = exports.getStreamFiles = exports.getStepFiles = void 0;
7
7
  const core_1 = require("@motiadev/core");
8
8
  const printer_1 = require("@motiadev/core/dist/src/printer");
9
+ const colors_1 = __importDefault(require("colors"));
9
10
  const crypto_1 = require("crypto");
10
11
  const glob_1 = require("glob");
11
12
  const path_1 = __importDefault(require("path"));
@@ -32,6 +33,7 @@ const collectFlows = async (projectDir, lockedData) => {
32
33
  const invalidSteps = [];
33
34
  const stepFiles = (0, exports.getStepFiles)(projectDir);
34
35
  const streamFiles = (0, exports.getStreamFiles)(projectDir);
36
+ const deprecatedSteps = (0, glob_1.globSync)('**/*.step.py', { absolute: true, cwd: path_1.default.join(projectDir, 'steps') });
35
37
  for (const filePath of stepFiles) {
36
38
  try {
37
39
  const config = await (0, core_1.getStepConfig)(filePath);
@@ -56,6 +58,25 @@ const collectFlows = async (projectDir, lockedData) => {
56
58
  }
57
59
  lockedData.createStream({ filePath, config }, { disableTypeCreation: true });
58
60
  }
61
+ if (deprecatedSteps.length > 0) {
62
+ const warning = colors_1.default.yellow('! [WARNING]');
63
+ console.warn(colors_1.default.yellow([
64
+ '',
65
+ '========================================',
66
+ warning,
67
+ '',
68
+ `Python steps with ${colors_1.default.gray('.step.py')} extensions are no longer supported.`,
69
+ `Please rename them to ${colors_1.default.gray('_step.py')}.`,
70
+ '',
71
+ colors_1.default.bold('Steps:'),
72
+ ...deprecatedSteps.map((step) => colors_1.default.reset(`- ${colors_1.default.cyan(colors_1.default.bold(step.replace(projectDir, '')))} rename to ${colors_1.default.gray(`${step.replace(projectDir, '').replace('.step.py', '_step.py')}`)}`)),
73
+ '',
74
+ 'Make sure the step names are importable from Python:',
75
+ `- Don't use numbers, dots, dashes, commas, spaces, colons, or special characters`,
76
+ '========================================',
77
+ '',
78
+ ].join('\n')));
79
+ }
59
80
  return invalidSteps;
60
81
  };
61
82
  exports.collectFlows = collectFlows;
@@ -137,10 +137,10 @@ class Watcher {
137
137
  .on('unlink', (path) => this.onFileDelete(path));
138
138
  }
139
139
  isStepFile(path) {
140
- return /[._]step\.[^.]+$/.test(path) && !/\.tsx$/.test(path);
140
+ return /[._]step\.[^.]+$/.test(path) && !/\.tsx$/.test(path) && !/\.step\.py$/.test(path);
141
141
  }
142
142
  isStreamFile(path) {
143
- return /[._]stream\.[^.]+$/.test(path) && !/\.tsx$/.test(path);
143
+ return /[._]stream\.[^.]+$/.test(path) && !/\.tsx$/.test(path) && !/\.stream\.py$/.test(path);
144
144
  }
145
145
  async stop() {
146
146
  if (this.watcher) {
@@ -28,4 +28,10 @@ describe('extractPythonData', () => {
28
28
  const requirements = readRequirements(path.join(rootDir, 'requirements.txt'), mockPackageDescriber);
29
29
  expect(() => extractPythonData(rootDir, `/steps/api_step.py`, requirements)).toThrow(new PythonError("Compilation error: no viable alternative at input ':' at line 3:10 in /steps/api_step.py", '/steps/api_step.py'));
30
30
  });
31
+ test('extracts python data with nested import from requirements', () => {
32
+ const rootDir = path.join(__dirname, './examples/chessarena');
33
+ const requirements = readRequirements(path.join(rootDir, 'requirements.txt'), mockPackageDescriber);
34
+ const result = extractPythonData(rootDir, `/steps/evaluate_player_move_step.py`, requirements);
35
+ expect(result.externalDependencies).toEqual({ chess: 'chess>=1.0.0', pydantic: 'pydantic>=2.6.1' });
36
+ });
31
37
  });
@@ -50,13 +50,14 @@ export const getDependenciesFromFile = (content, path, requirements) => {
50
50
  projectDependencies: new Set(),
51
51
  };
52
52
  for (const module of modulesSet) {
53
+ const [moduleName] = module.split('.');
53
54
  if (module[0] === '.') {
54
55
  dependencies.projectDependencies.add(module);
55
56
  }
56
57
  else if (STANDARD_LIB_MODULES.has(module)) {
57
58
  dependencies.standardLibDependencies.add(module);
58
59
  }
59
- else if (requirements[module]) {
60
+ else if (requirements[module] || requirements[moduleName]) {
60
61
  dependencies.externalDependencies.add(module);
61
62
  }
62
63
  else {
@@ -1,5 +1,6 @@
1
1
  import { LockedData, getStepConfig, getStreamConfig } from '@motiadev/core';
2
2
  import { NoPrinter, Printer } from '@motiadev/core/dist/src/printer';
3
+ import colors from 'colors';
3
4
  import { randomUUID } from 'crypto';
4
5
  import { globSync } from 'glob';
5
6
  import path from 'path';
@@ -24,6 +25,7 @@ export const collectFlows = async (projectDir, lockedData) => {
24
25
  const invalidSteps = [];
25
26
  const stepFiles = getStepFiles(projectDir);
26
27
  const streamFiles = getStreamFiles(projectDir);
28
+ const deprecatedSteps = globSync('**/*.step.py', { absolute: true, cwd: path.join(projectDir, 'steps') });
27
29
  for (const filePath of stepFiles) {
28
30
  try {
29
31
  const config = await getStepConfig(filePath);
@@ -48,6 +50,25 @@ export const collectFlows = async (projectDir, lockedData) => {
48
50
  }
49
51
  lockedData.createStream({ filePath, config }, { disableTypeCreation: true });
50
52
  }
53
+ if (deprecatedSteps.length > 0) {
54
+ const warning = colors.yellow('! [WARNING]');
55
+ console.warn(colors.yellow([
56
+ '',
57
+ '========================================',
58
+ warning,
59
+ '',
60
+ `Python steps with ${colors.gray('.step.py')} extensions are no longer supported.`,
61
+ `Please rename them to ${colors.gray('_step.py')}.`,
62
+ '',
63
+ colors.bold('Steps:'),
64
+ ...deprecatedSteps.map((step) => colors.reset(`- ${colors.cyan(colors.bold(step.replace(projectDir, '')))} rename to ${colors.gray(`${step.replace(projectDir, '').replace('.step.py', '_step.py')}`)}`)),
65
+ '',
66
+ 'Make sure the step names are importable from Python:',
67
+ `- Don't use numbers, dots, dashes, commas, spaces, colons, or special characters`,
68
+ '========================================',
69
+ '',
70
+ ].join('\n')));
71
+ }
51
72
  return invalidSteps;
52
73
  };
53
74
  export const generateLockedData = async (projectDir, streamAdapter = 'file', printerType = 'default') => {
@@ -131,10 +131,10 @@ export class Watcher {
131
131
  .on('unlink', (path) => this.onFileDelete(path));
132
132
  }
133
133
  isStepFile(path) {
134
- return /[._]step\.[^.]+$/.test(path) && !/\.tsx$/.test(path);
134
+ return /[._]step\.[^.]+$/.test(path) && !/\.tsx$/.test(path) && !/\.step\.py$/.test(path);
135
135
  }
136
136
  isStreamFile(path) {
137
- return /[._]stream\.[^.]+$/.test(path) && !/\.tsx$/.test(path);
137
+ return /[._]stream\.[^.]+$/.test(path) && !/\.tsx$/.test(path) && !/\.stream\.py$/.test(path);
138
138
  }
139
139
  async stop() {
140
140
  if (this.watcher) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "motia",
3
3
  "description": "A Modern Unified Backend Framework for APIs, Events and Agents",
4
- "version": "0.6.4-beta.131-211436",
4
+ "version": "0.6.4-beta.131-014082",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -46,9 +46,9 @@
46
46
  "python-ast": "^0.1.0",
47
47
  "table": "^6.9.0",
48
48
  "ts-node": "^10.9.2",
49
- "@motiadev/core": "0.6.4-beta.131-211436",
50
- "@motiadev/workbench": "0.6.4-beta.131-211436",
51
- "@motiadev/stream-client-node": "0.6.4-beta.131-211436"
49
+ "@motiadev/stream-client-node": "0.6.4-beta.131-014082",
50
+ "@motiadev/workbench": "0.6.4-beta.131-014082",
51
+ "@motiadev/core": "0.6.4-beta.131-014082"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@amplitude/analytics-types": "^2.9.2",