programgarden 1.22.0__tar.gz → 1.22.1__tar.gz

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 (34) hide show
  1. {programgarden-1.22.0 → programgarden-1.22.1}/PKG-INFO +4 -4
  2. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/resolver.py +68 -0
  3. {programgarden-1.22.0 → programgarden-1.22.1}/pyproject.toml +4 -4
  4. {programgarden-1.22.0 → programgarden-1.22.1}/README.md +0 -0
  5. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/__init__.py +0 -0
  6. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/binding_validator.py +0 -0
  7. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/client.py +0 -0
  8. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/context.py +0 -0
  9. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/database/__init__.py +0 -0
  10. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/database/checkpoint_manager.py +0 -0
  11. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/database/query_builder.py +0 -0
  12. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/database/workflow_position_tracker.py +0 -0
  13. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/database/workflow_risk_tracker.py +0 -0
  14. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/executor.py +0 -0
  15. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/node_runner.py +0 -0
  16. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/plugin/__init__.py +0 -0
  17. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/plugin/sandbox.py +0 -0
  18. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/providers/__init__.py +0 -0
  19. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/providers/llm_errors.py +0 -0
  20. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/providers/llm_provider.py +0 -0
  21. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/reconnect_handler.py +0 -0
  22. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/resource/__init__.py +0 -0
  23. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/resource/context.py +0 -0
  24. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/resource/limiter.py +0 -0
  25. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/resource/monitor.py +0 -0
  26. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/resource/throttle.py +0 -0
  27. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/tools/__init__.py +0 -0
  28. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/tools/credential_tools.py +0 -0
  29. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/tools/definition_tools.py +0 -0
  30. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/tools/event_tools.py +0 -0
  31. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/tools/job_tools.py +0 -0
  32. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/tools/registry_tools.py +0 -0
  33. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/tools/sqlite_tools.py +0 -0
  34. {programgarden-1.22.0 → programgarden-1.22.1}/programgarden/validation_recommender.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: programgarden
3
- Version: 1.22.0
3
+ Version: 1.22.1
4
4
  Summary: ProgramGarden - 노드 기반 자동매매 DSL 실행 엔진
5
5
  Author: 프로그램동산
6
6
  Author-email: coding@programgarden.com
@@ -13,9 +13,9 @@ Requires-Dist: aiosqlite (>=0.20.0,<0.21.0)
13
13
  Requires-Dist: croniter (>=6.0.0,<7.0.0)
14
14
  Requires-Dist: litellm (>=1.40.0)
15
15
  Requires-Dist: lxml (>=6.0.2,<7.0.0)
16
- Requires-Dist: programgarden-community (>=1.13.5,<2.0.0)
17
- Requires-Dist: programgarden-core (>=1.13.0,<2.0.0)
18
- Requires-Dist: programgarden-finance (>=1.6.7,<2.0.0)
16
+ Requires-Dist: programgarden-community (>=1.13.7,<2.0.0)
17
+ Requires-Dist: programgarden-core (>=1.14.1,<2.0.0)
18
+ Requires-Dist: programgarden-finance (>=1.6.8,<2.0.0)
19
19
  Requires-Dist: psutil (>=6.0.0,<7.0.0)
20
20
  Requires-Dist: psycopg2-binary (>=2.9.11,<3.0.0)
21
21
  Requires-Dist: pydantic (>=2.0.0,<3.0.0)
@@ -274,6 +274,74 @@ class WorkflowResolver:
274
274
  suggestion="Install programgarden-community or register the plugin manually.",
275
275
  )
276
276
  )
277
+ else:
278
+ # Plugin exists — verify the data binding shape matches the
279
+ # plugin's contract. Mirrors the runtime branch in
280
+ # executor (_execute_condition_node): position-management
281
+ # plugins read `positions`, indicator plugins iterate
282
+ # `items {from, extract}`. Without this static check the
283
+ # wrong shape (legacy `data`/`params`) passes validate()
284
+ # and only fails at dry_run, so the AI build self-correct
285
+ # loop never sees it.
286
+ plugin_schema = plugin_registry.get_schema(plugin_id)
287
+ required_data = (
288
+ plugin_schema.required_data if plugin_schema else ["data"]
289
+ )
290
+ is_positions_based = (
291
+ "positions" in required_data and "data" not in required_data
292
+ )
293
+ if is_positions_based:
294
+ if not node.get("positions"):
295
+ result.add(
296
+ build_error(
297
+ ErrorCode.MISSING_REQUIRED_FIELD,
298
+ f"ConditionNode '{node.get('id')}' uses position "
299
+ f"plugin '{plugin_id}' but has no 'positions' binding",
300
+ location=ErrorLocation(
301
+ node_id=node.get("id"),
302
+ node_type=node.get("type"),
303
+ plugin_id=plugin_id,
304
+ field_path="positions",
305
+ ),
306
+ suggestion=(
307
+ "Position-management plugins (StopLoss / "
308
+ "ProfitTarget / TrailingStop) read holdings from "
309
+ "'positions'. Bind it to an account node's "
310
+ "positions output, e.g. positions: "
311
+ "'{{ nodes.account.positions }}'. The 'data' / "
312
+ "'params' fields are not used here."
313
+ ),
314
+ )
315
+ )
316
+ else:
317
+ items = node.get("items")
318
+ if (
319
+ not isinstance(items, dict)
320
+ or not items.get("from")
321
+ or not items.get("extract")
322
+ ):
323
+ result.add(
324
+ build_error(
325
+ ErrorCode.MISSING_REQUIRED_FIELD,
326
+ f"ConditionNode '{node.get('id')}' uses indicator "
327
+ f"plugin '{plugin_id}' but has no valid 'items' "
328
+ f"binding (items.from + items.extract)",
329
+ location=ErrorLocation(
330
+ node_id=node.get("id"),
331
+ node_type=node.get("type"),
332
+ plugin_id=plugin_id,
333
+ field_path="items",
334
+ ),
335
+ suggestion=(
336
+ "Indicator plugins iterate OHLCV through 'items'. "
337
+ "Add items with 'from' (the source array) and "
338
+ "'extract' (per-row field map), e.g. items: "
339
+ "{from: '{{ item.time_series }}', extract: "
340
+ "{symbol, exchange, date, close}}. The legacy "
341
+ "'data' / 'params' fields are not used."
342
+ ),
343
+ )
344
+ )
277
345
 
278
346
  # 5. 노드 연결 규칙 검증 (실시간 → 위험 노드 직결 차단)
279
347
  self._validate_connection_rules(workflow, registry, result)
@@ -5,7 +5,7 @@ authors = [
5
5
  homepage = "https://programgarden.com"
6
6
  requires-python = ">=3.12"
7
7
  name = "programgarden"
8
- version = "1.22.0"
8
+ version = "1.22.1"
9
9
  description = "ProgramGarden - 노드 기반 자동매매 DSL 실행 엔진"
10
10
  readme = "README.md"
11
11
 
@@ -28,9 +28,9 @@ lxml = "^6.0.2"
28
28
  pytickersymbols = {version = ">=1.17.5", python = ">=3.12,<4.0"}
29
29
  aiosqlite = "^0.20.0"
30
30
  litellm = ">=1.40.0"
31
- programgarden-core = "^1.13.0"
32
- programgarden-finance = "^1.6.7"
33
- programgarden-community = "^1.13.5"
31
+ programgarden-core = "^1.14.1"
32
+ programgarden-finance = "^1.6.8"
33
+ programgarden-community = "^1.13.7"
34
34
 
35
35
  [tool.poetry.group.dev.dependencies]
36
36
  pytest = "^8.0.0"
File without changes