ApiLogicServer 12.1.0__py3-none-any.whl → 12.2.0__py3-none-any.whl
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.
- {ApiLogicServer-12.1.0.dist-info → ApiLogicServer-12.2.0.dist-info}/METADATA +1 -1
- {ApiLogicServer-12.1.0.dist-info → ApiLogicServer-12.2.0.dist-info}/RECORD +47 -39
- {ApiLogicServer-12.1.0.dist-info → ApiLogicServer-12.2.0.dist-info}/WHEEL +1 -1
- api_logic_server_cli/api_logic_server.py +15 -4
- api_logic_server_cli/api_logic_server_info.yaml +3 -3
- api_logic_server_cli/cli.py +20 -9
- api_logic_server_cli/cli_args_base.py +2 -0
- api_logic_server_cli/cli_args_project.py +9 -3
- api_logic_server_cli/create_from_model/__pycache__/ont_create.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/ui_admin_creator.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/ont_create.py +3 -1
- api_logic_server_cli/create_from_model/ui_admin_creator.py +6 -4
- api_logic_server_cli/genai.py +387 -287
- api_logic_server_cli/logging.yml +5 -0
- api_logic_server_cli/prototypes/.DS_Store +0 -0
- api_logic_server_cli/prototypes/base/api_logic_server_run.py +0 -2
- api_logic_server_cli/prototypes/base/config/server_setup.py +15 -1
- api_logic_server_cli/prototypes/base/integration/kafka/kafka_consumer.py +1 -1
- api_logic_server_cli/prototypes/base/integration/kafka/kafka_producer.py +1 -1
- api_logic_server_cli/prototypes/base/readme.md +21 -8
- api_logic_server_cli/prototypes/manager/.DS_Store +0 -0
- api_logic_server_cli/prototypes/manager/.vscode/.DS_Store +0 -0
- api_logic_server_cli/prototypes/manager/.vscode/launch.json +20 -0
- api_logic_server_cli/prototypes/manager/README.md +25 -1
- api_logic_server_cli/prototypes/manager/system/.DS_Store +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/.DS_Store +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_create_db.py +1 -0
- api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_imports.py +10 -7
- api_logic_server_cli/prototypes/manager/system/genai/create_db_models_inserts/create_db_models_test_data.py +1 -1
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example +99 -22
- api_logic_server_cli/prototypes/manager/system/genai/learning_requests/logic_bank_api.prompt +120 -7
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/.DS_Store +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/response_format.prompt +26 -2
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/sqlite_inserts.prompt +10 -4
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/{sqlite_inserts_iterations.prompt → zsqlite_inserts_iterations.prompt} +5 -2
- api_logic_server_cli/prototypes/manager/system/genai/retry/conv/create_db_models.py +96 -0
- api_logic_server_cli/prototypes/manager/system/genai/retry/conv/inf-1_iter_1_1_000.response +1 -0
- api_logic_server_cli/prototypes/manager/system/genai/retry/conv/inf-1_iter_1_1_001.prompt +208 -0
- api_logic_server_cli/prototypes/manager/system/genai/retry/conv/inf-1_iter_1_1_002.prompt +89 -0
- api_logic_server_cli/prototypes/manager/system/genai/retry/conv/inf-1_iter_1_1_003.prompt +40 -0
- api_logic_server_cli/prototypes/manager/system/genai/retry/conv/inf-1_iter_1_1_004.response +57 -0
- api_logic_server_cli/prototypes/manager/system/genai/retry/conv/inf-1_iter_1_1_005.response +57 -0
- api_logic_server_cli/prototypes/manager/system/genai/retry/readme.md +1 -0
- api_logic_server_cli/prototypes/manager/system/genai/retry/retry.response +57 -0
- api_logic_server_cli/genaiZ.py +0 -752
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example_z +0 -130
- api_logic_server_cli/prototypes/manager/system/genai/prompt_inserts/web_genai copy.prompt +0 -15
- api_logic_server_cli/prototypes/manager/system/secrets.txt +0 -6
- {ApiLogicServer-12.1.0.dist-info → ApiLogicServer-12.2.0.dist-info}/LICENSE +0 -0
- {ApiLogicServer-12.1.0.dist-info → ApiLogicServer-12.2.0.dist-info}/entry_points.txt +0 -0
- {ApiLogicServer-12.1.0.dist-info → ApiLogicServer-12.2.0.dist-info}/top_level.txt +0 -0
api_logic_server_cli/logging.yml
CHANGED
|
Binary file
|
|
@@ -68,8 +68,6 @@ import ui.admin.admin_loader as AdminLoader
|
|
|
68
68
|
from security.system.authentication import configure_auth
|
|
69
69
|
import database.multi_db as multi_db
|
|
70
70
|
import oracledb
|
|
71
|
-
import integration.kafka.kafka_producer as kafka_producer
|
|
72
|
-
import integration.kafka.kafka_consumer as kafka_consumer
|
|
73
71
|
|
|
74
72
|
|
|
75
73
|
app_logger = server_setup.logging_setup()
|
|
@@ -317,7 +317,21 @@ def api_logic_server_setup(flask_app: Flask, args: Args):
|
|
|
317
317
|
if logic_logger_activate_debug == False:
|
|
318
318
|
logic_logger.setLevel(logging.INFO)
|
|
319
319
|
app_logger.info("")
|
|
320
|
-
|
|
320
|
+
disable_rules = False
|
|
321
|
+
if os.getenv('APILOGICPROJECT_DISABLE_RULES'):
|
|
322
|
+
disable_rules = os.getenv('APILOGICPROJECT_DISABLE_RULES').startswith("1") or \
|
|
323
|
+
os.getenv('APILOGICPROJECT_DISABLE_RULES').startswith("T") or \
|
|
324
|
+
os.getenv('APILOGICPROJECT_DISABLE_RULES').startswith("t") or \
|
|
325
|
+
os.getenv('APILOGICPROJECT_DISABLE_RULES').startswith("Y") or \
|
|
326
|
+
os.getenv('APILOGICPROJECT_DISABLE_RULES').startswith("y")
|
|
327
|
+
if disable_rules:
|
|
328
|
+
app_logger.info("LogicBank rules disabled") # db opened 1st access
|
|
329
|
+
else: # genai may insert rules with no columns... WebG restarts with rules disabled
|
|
330
|
+
try:
|
|
331
|
+
LogicBank.activate(session=session, activator=declare_logic.declare_logic, constraint_event=constraint_handler)
|
|
332
|
+
except Exception as e:
|
|
333
|
+
app_logger.error("Logic Bank Activation Error: " + str(e))
|
|
334
|
+
app_logger.exception(e)
|
|
321
335
|
logic_logger.setLevel(logic_logger_level)
|
|
322
336
|
app_logger.info("Declare Logic complete - logic/declare_logic.py (rules + code)"
|
|
323
337
|
+ f' -- {len(database.models.metadata.tables)} tables loaded\n') # db opened 1st access
|
|
@@ -98,19 +98,32 @@ As shown above:
|
|
|
98
98
|
|
|
99
99
|
Your project is ready to run, but it's likely you'll want to customize it - declare logic, new endpoints, etc.
|
|
100
100
|
|
|
101
|
-
>> Tip: in particular, use the sample app to explore the value of ___declarative logic and security.___ Unique to API Logic Server, this is critical to unlocking the full value of API Logic Server.
|
|
102
101
|
|
|
103
|
-
|
|
102
|
+
<details markdown>
|
|
104
103
|
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
<summary>Important: explore customization examples</summary>
|
|
105
|
+
<br>
|
|
106
|
+
In particular, use the sample app to explore the value of declarative logic and security. Unique to API Logic Server, these are critical to unlocking the full value of API Logic Server.
|
|
107
107
|
|
|
108
|
-
>
|
|
109
|
-
|
|
108
|
+
<br>
|
|
109
|
+
|
|
110
|
+
To create the sample app for customization examples:
|
|
111
|
+
|
|
112
|
+
* `ApiLogicServer create --project-name=nw_sample --db_url=nw+`
|
|
113
|
+
* Or, open it in GitHub (use Shift + "." to view in project mode) - [click here](https://github.com/ApiLogicServer/demo)
|
|
110
114
|
|
|
111
|
-
To make customizations easy to explore,
|
|
115
|
+
To make customizations easy to explore, search for:
|
|
112
116
|
* `#als` will reveal key customization examples
|
|
113
|
-
* `Your Code Goes Here` to find key files to customize, summarized below
|
|
117
|
+
* `Your Code Goes Here` to find key files to customize, summarized in the table below.
|
|
118
|
+
|
|
119
|
+
</details>
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
The ___Key Customization Files___ listed in the table below are created as stubs, intended for you to add customizations that extend the created API, Logic and Web App.
|
|
124
|
+
|
|
125
|
+
* Since they are separate files, the project can be
|
|
126
|
+
[rebuilt](https://apilogicserver.github.io/Docs/Project-Rebuild/) (e.g., synchronized with a revised schema), preserving your customizations.
|
|
114
127
|
|
|
115
128
|
<br>
|
|
116
129
|
|
|
Binary file
|
|
Binary file
|
|
@@ -295,6 +295,26 @@
|
|
|
295
295
|
"console": "internalConsole",
|
|
296
296
|
"internalConsoleOptions": "openOnSessionStart"
|
|
297
297
|
},
|
|
298
|
+
{
|
|
299
|
+
"name": " - retry conversation",
|
|
300
|
+
"type": "debugpy",
|
|
301
|
+
"request": "launch",
|
|
302
|
+
"program": "${workspaceFolder}/venv/lib/python3.12/site-packages/api_logic_server_cli/cli.py",
|
|
303
|
+
"redirectOutput": true,
|
|
304
|
+
"cwd": "${workspaceFolder}",
|
|
305
|
+
"env": {
|
|
306
|
+
"PYTHONPATH": "",
|
|
307
|
+
"SECURITY_ENABLED": "False",
|
|
308
|
+
"PYTHONHASHSEED": "0",
|
|
309
|
+
"APILOGICSERVER_DEBUG": "False",
|
|
310
|
+
"OPT_LOCKING": "optional"},
|
|
311
|
+
"justMyCode": false,
|
|
312
|
+
"args": [ "genai", "--retries=-1",
|
|
313
|
+
"--using=retry-project",
|
|
314
|
+
"--using=system/genai/retry/conv"],
|
|
315
|
+
"console": "internalConsole",
|
|
316
|
+
"internalConsoleOptions": "openOnSessionStart"
|
|
317
|
+
},
|
|
298
318
|
{
|
|
299
319
|
"name": "Python: Module",
|
|
300
320
|
"type": "debugpy",
|
|
@@ -194,7 +194,6 @@ als genai --project-name='genai_demo_conversation' --using=system/genai/examples
|
|
|
194
194
|
```
|
|
195
195
|
</details>
|
|
196
196
|
</br>
|
|
197
|
-
|
|
198
197
|
<details markdown>
|
|
199
198
|
|
|
200
199
|
<summary> You can iterate with logic</summary>
|
|
@@ -210,6 +209,31 @@ als genai --project-name='genai_demo_iterative_logic' --using=system/genai/examp
|
|
|
210
209
|
|
|
211
210
|
<details markdown>
|
|
212
211
|
|
|
212
|
+
<summary> You can declare informal logic</summary>
|
|
213
|
+
|
|
214
|
+
<br>You can declare rules using dot notation, or more informally:
|
|
215
|
+
|
|
216
|
+
```bash title="Informal Logic (no dot notation)"
|
|
217
|
+
als genai --using=system/genai/examples/genai_demo/genai_demo_informal.prompt
|
|
218
|
+
```
|
|
219
|
+
</details>
|
|
220
|
+
</br>
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
<details markdown>
|
|
224
|
+
|
|
225
|
+
<summary> Multi-Rule Logic</summary>
|
|
226
|
+
|
|
227
|
+
<br>You can add new columns/tables, while keeping the prior model intact:
|
|
228
|
+
|
|
229
|
+
```bash title="Multi-Rule Logic"
|
|
230
|
+
als genai --using=system/genai/examples/emp_depts/emp_dept.prompt
|
|
231
|
+
```
|
|
232
|
+
</details>
|
|
233
|
+
</br>
|
|
234
|
+
|
|
235
|
+
<details markdown>
|
|
236
|
+
|
|
213
237
|
<summary> You can also execute directly, and iterate</summary>
|
|
214
238
|
|
|
215
239
|
<br>You can add new columns/tables, while keeping the prior model intact:
|
|
Binary file
|
|
Binary file
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
# created from response
|
|
2
|
-
#
|
|
3
|
-
#
|
|
1
|
+
# created from response, to create create_db_models.sqlite, with test data
|
|
2
|
+
# that is used to create project
|
|
3
|
+
# should run without error in manager
|
|
4
|
+
# if not, check for decimal, indent, or import issues
|
|
4
5
|
|
|
5
6
|
import decimal
|
|
6
7
|
import logging
|
|
7
8
|
import sqlalchemy
|
|
8
|
-
from sqlalchemy.sql import func
|
|
9
|
+
from sqlalchemy.sql import func
|
|
9
10
|
from logic_bank.logic_bank import Rule
|
|
10
11
|
from sqlalchemy import create_engine, Column, Integer, String, Float, ForeignKey, Date, DateTime, Numeric, Boolean, Text
|
|
12
|
+
from sqlalchemy.types import *
|
|
11
13
|
from sqlalchemy.ext.declarative import declarative_base
|
|
12
14
|
from sqlalchemy.orm import sessionmaker
|
|
13
|
-
from datetime import datetime
|
|
14
15
|
from sqlalchemy.orm import relationship
|
|
15
|
-
from datetime import date
|
|
16
|
+
from datetime import date
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
logging.getLogger('sqlalchemy.engine.Engine').disabled = True # remove for additional logging
|
|
18
21
|
|
|
19
|
-
Base = declarative_base()
|
|
22
|
+
Base = declarative_base() # from system/genai/create_db_models_inserts/create_db_models_prefix.py
|
api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo.response_example
CHANGED
|
@@ -2,55 +2,132 @@
|
|
|
2
2
|
"models": [
|
|
3
3
|
{
|
|
4
4
|
"classname": "Customer",
|
|
5
|
-
"code": "
|
|
6
|
-
"
|
|
7
|
-
"
|
|
5
|
+
"code": "class Customer(Base):\n __tablename__ = 'customers'\n id = Column(Integer, primary_key=True, autoincrement=True)\n name = Column(String, nullable=False)\n balance = Column(Integer, default=0)\n credit_limit = Column(Integer, nullable=False)\n\n def __repr__(self):\n return f\"Customer(id={self.id}, name='{self.name}', balance={self.balance}, credit_limit={self.credit_limit})\"",
|
|
6
|
+
"sqlite_create": "CREATE TABLE customers (\n id INTEGER PRIMARY KEY AUTOINCREMENT, \n name VARCHAR NOT NULL, \n balance INTEGER DEFAULT 0, \n credit_limit INTEGER NOT NULL\n)",
|
|
7
|
+
"description": "description: Customers table",
|
|
8
|
+
"name": "customers"
|
|
8
9
|
},
|
|
9
10
|
{
|
|
10
11
|
"classname": "Order",
|
|
11
|
-
"code": "
|
|
12
|
-
"
|
|
13
|
-
"
|
|
12
|
+
"code": "class Order(Base):\n __tablename__ = 'orders'\n id = Column(Integer, primary_key=True, autoincrement=True)\n customer_id = Column(Integer, ForeignKey('customers.id'))\n notes = Column(String)\n date_shipped = Column(Date)\n amount_total = Column(Integer, default=0)\n\n def __repr__(self):\n return f\"Order(id={self.id}, customer_id={self.customer_id}, notes='{self.notes}', amount_total={self.amount_total}, date_shipped={self.date_shipped})\"",
|
|
13
|
+
"sqlite_create": "CREATE TABLE orders (\n id INTEGER PRIMARY KEY AUTOINCREMENT, \n customer_id INTEGER, \n notes VARCHAR, \n date_shipped DATE, \n amount_total INTEGER DEFAULT 0, \n FOREIGN KEY(customer_id) REFERENCES customers (id)\n)",
|
|
14
|
+
"description": "description: Orders table",
|
|
15
|
+
"name": "orders"
|
|
14
16
|
},
|
|
15
17
|
{
|
|
16
18
|
"classname": "Item",
|
|
17
|
-
"code": "
|
|
18
|
-
"
|
|
19
|
-
"
|
|
19
|
+
"code": "class Item(Base):\n __tablename__ = 'items'\n id = Column(Integer, primary_key=True, autoincrement=True)\n order_id = Column(Integer, ForeignKey('orders.id'))\n product_id = Column(Integer, ForeignKey('products.id'))\n quantity = Column(Integer, nullable=False)\n unit_price = Column(Integer, nullable=False)\n amount = Column(Integer, default=0)\n\n def __repr__(self):\n return f\"Item(id={self.id}, order_id={self.order_id}, product_id={self.product_id}, quantity={self.quantity}, unit_price={self.unit_price}, amount={self.amount})\"",
|
|
20
|
+
"sqlite_create": "CREATE TABLE items (\n id INTEGER PRIMARY KEY AUTOINCREMENT, \n order_id INTEGER, \n product_id INTEGER, \n quantity INTEGER NOT NULL, \n unit_price INTEGER NOT NULL, \n amount INTEGER DEFAULT 0, \n FOREIGN KEY(order_id) REFERENCES orders (id), \n FOREIGN KEY(product_id) REFERENCES products (id)\n)",
|
|
21
|
+
"description": "description: Items table",
|
|
22
|
+
"name": "items"
|
|
20
23
|
},
|
|
21
24
|
{
|
|
22
25
|
"classname": "Product",
|
|
23
|
-
"code": "
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
+
"code": "class Product(Base):\n __tablename__ = 'products'\n id = Column(Integer, primary_key=True, autoincrement=True)\n name = Column(String, nullable=False)\n unit_price = Column(Integer, nullable=False)\n\n def __repr__(self):\n return f\"Product(id={self.id}, name='{self.name}', unit_price={self.unit_price})\"",
|
|
27
|
+
"sqlite_create": "CREATE TABLE products (\n id INTEGER PRIMARY KEY AUTOINCREMENT, \n name VARCHAR NOT NULL, \n unit_price INTEGER NOT NULL\n)",
|
|
28
|
+
"description": "description: Products table",
|
|
29
|
+
"name": "products"
|
|
26
30
|
}
|
|
27
31
|
],
|
|
28
32
|
"rules": [
|
|
29
33
|
{
|
|
30
34
|
"name": "Customer Balance Constraint",
|
|
31
|
-
"description": "Ensures
|
|
35
|
+
"description": "Ensures the customer's balance does not exceed the credit limit.",
|
|
36
|
+
"use_case": "Customer.balance <= credit_limit",
|
|
32
37
|
"code": "Rule.constraint(validate=Customer,\n as_condition=lambda row: row.balance <= row.credit_limit,\n error_msg=\"Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})\")"
|
|
33
38
|
},
|
|
34
39
|
{
|
|
35
|
-
"name": "Customer Balance
|
|
36
|
-
"description": "Calculates the customer's balance as the sum of
|
|
40
|
+
"name": "Customer Balance Derivation",
|
|
41
|
+
"description": "Calculates the customer's balance as the sum of orders' amount_total where date_shipped is null.",
|
|
42
|
+
"use_case": "Customer.balance = Sum(Order.amount_total where date_shipped is null)",
|
|
37
43
|
"code": "Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total, where=lambda row: row.date_shipped is None)"
|
|
38
44
|
},
|
|
39
45
|
{
|
|
40
|
-
"name": "Order Amount Total
|
|
41
|
-
"description": "Calculates
|
|
46
|
+
"name": "Order Amount Total Derivation",
|
|
47
|
+
"description": "Calculates order's amount_total as the sum of item amounts.",
|
|
48
|
+
"use_case": "Order.amount_total = Sum(Item.amount)",
|
|
42
49
|
"code": "Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)"
|
|
43
50
|
},
|
|
44
51
|
{
|
|
45
|
-
"name": "Item Amount
|
|
46
|
-
"description": "Calculates
|
|
52
|
+
"name": "Item Amount Derivation",
|
|
53
|
+
"description": "Calculates item amount as quantity multiplied by unit price.",
|
|
54
|
+
"use_case": "Item.amount = quantity * unit_price",
|
|
47
55
|
"code": "Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)"
|
|
48
56
|
},
|
|
49
57
|
{
|
|
50
|
-
"name": "Item Unit Price
|
|
51
|
-
"description": "Copies the unit price
|
|
58
|
+
"name": "Copy Item Unit Price",
|
|
59
|
+
"description": "Copies the product's unit price to the item.",
|
|
60
|
+
"use_case": "Store the Item.unit_price as a copy from Product.unit_price",
|
|
52
61
|
"code": "Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)"
|
|
53
62
|
}
|
|
54
63
|
],
|
|
55
|
-
"test_data": "
|
|
64
|
+
"test_data": "Insert test data into the tables with values compatible with the derived logic.",
|
|
65
|
+
"test_data_rows": [
|
|
66
|
+
{
|
|
67
|
+
"test_data_row_variable": "test_customer_1",
|
|
68
|
+
"code": "test_customer_1 = Customer(name='Customer 1', balance=300, credit_limit=1000)"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"test_data_row_variable": "test_customer_2",
|
|
72
|
+
"code": "test_customer_2 = Customer(name='Customer 2', balance=500, credit_limit=750)"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"test_data_row_variable": "test_customer_3",
|
|
76
|
+
"code": "test_customer_3 = Customer(name='Customer 3', balance=0, credit_limit=1500)"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"test_data_row_variable": "test_customer_4",
|
|
80
|
+
"code": "test_customer_4 = Customer(name='Customer 4', balance=200, credit_limit=1200)"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"test_data_row_variable": "test_order_1",
|
|
84
|
+
"code": "test_order_1 = Order(customer_id=1, notes='Order 1 notes', amount_total=150)"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"test_data_row_variable": "test_order_2",
|
|
88
|
+
"code": "test_order_2 = Order(customer_id=2, notes='Order 2 notes', amount_total=0)"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"test_data_row_variable": "test_order_3",
|
|
92
|
+
"code": "test_order_3 = Order(customer_id=2, notes='Order 3 notes', amount_total=0)"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"test_data_row_variable": "test_order_4",
|
|
96
|
+
"code": "test_order_4 = Order(customer_id=3, notes='Order 4 notes', amount_total=150)"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"test_data_row_variable": "test_item_1",
|
|
100
|
+
"code": "test_item_1 = Item(order_id=1, product_id=1, quantity=3, unit_price=50, amount=150)"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"test_data_row_variable": "test_item_2",
|
|
104
|
+
"code": "test_item_2 = Item(order_id=2, product_id=2, quantity=2, unit_price=0, amount=0)"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"test_data_row_variable": "test_item_3",
|
|
108
|
+
"code": "test_item_3 = Item(order_id=3, product_id=3, quantity=1, unit_price=0, amount=0)"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"test_data_row_variable": "test_item_4",
|
|
112
|
+
"code": "test_item_4 = Item(order_id=4, product_id=1, quantity=3, unit_price=50, amount=150)"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"test_data_row_variable": "test_product_1",
|
|
116
|
+
"code": "test_product_1 = Product(name='Product 1', unit_price=50)"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"test_data_row_variable": "test_product_2",
|
|
120
|
+
"code": "test_product_2 = Product(name='Product 2', unit_price=25)"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"test_data_row_variable": "test_product_3",
|
|
124
|
+
"code": "test_product_3 = Product(name='Product 3', unit_price=75)"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"test_data_row_variable": "test_product_4",
|
|
128
|
+
"code": "test_product_4 = Product(name='Product 4', unit_price=100)"
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
"test_data_sqlite": "INSERT INTO customers (name, balance, credit_limit) VALUES ('Customer 1', 300, 1000);\nINSERT INTO customers (name, balance, credit_limit) VALUES ('Customer 2', 500, 750);\nINSERT INTO customers (name, balance, credit_limit) VALUES ('Customer 3', 0, 1500);\nINSERT INTO customers (name, balance, credit_limit) VALUES ('Customer 4', 200, 1200);\n\nINSERT INTO orders (customer_id, notes, date_shipped, amount_total) VALUES (1, 'Order 1 notes', NULL, 150);\nINSERT INTO orders (customer_id, notes, date_shipped, amount_total) VALUES (2, 'Order 2 notes', NULL, 0);\nINSERT INTO orders (customer_id, notes, date_shipped, amount_total) VALUES (2, 'Order 3 notes', NULL, 0);\nINSERT INTO orders (customer_id, notes, date_shipped, amount_total) VALUES (3, 'Order 4 notes', NULL, 150);\n\nINSERT INTO items (order_id, product_id, quantity, unit_price, amount) VALUES (1, 1, 3, 50, 150);\nINSERT INTO items (order_id, product_id, quantity, unit_price, amount) VALUES (2, 2, 2, 25, 0);\nINSERT INTO items (order_id, product_id, quantity, unit_price, amount) VALUES (3, 3, 1, 75, 0);\nINSERT INTO items (order_id, product_id, quantity, unit_price, amount) VALUES (4, 1, 3, 50, 150);\n\nINSERT INTO products (name, unit_price) VALUES ('Product 1', 50);\nINSERT INTO products (name, unit_price) VALUES ('Product 2', 25);\nINSERT INTO products (name, unit_price) VALUES ('Product 3', 75);\nINSERT INTO products (name, unit_price) VALUES ('Product 4', 100);",
|
|
132
|
+
"name": "OrderManagementSystem"
|
|
56
133
|
}
|
api_logic_server_cli/prototypes/manager/system/genai/learning_requests/logic_bank_api.prompt
CHANGED
|
@@ -4,6 +4,8 @@ Create a function called declare_logic(), consisting of calls to Rule methods.
|
|
|
4
4
|
|
|
5
5
|
Do not generate import statements.
|
|
6
6
|
|
|
7
|
+
If you create sum, count or formula LogicBank rules, you MUST create a corresponding column in the data model.
|
|
8
|
+
|
|
7
9
|
Use only the methods provided below.
|
|
8
10
|
|
|
9
11
|
class Rule:
|
|
@@ -25,8 +27,8 @@ class Rule:
|
|
|
25
27
|
derive: name of parent <class.attribute> being derived
|
|
26
28
|
as_sum_of: name of child <class.attribute> being summed
|
|
27
29
|
child_role_name: parent's child accessor attribute (required only for disambiguation)
|
|
28
|
-
where: optional where clause, designates which child rows are summed
|
|
29
|
-
|
|
30
|
+
where: optional where clause, designates which child rows are summed. Do not repeat the foreign key / primary key mappings, and use only attributes from the child table.
|
|
31
|
+
insert_parent: create parent if it does not exist. Do not use unless directly requested.
|
|
30
32
|
"""
|
|
31
33
|
return Sum(derive, as_sum_of, where, child_role_name, insert_parent)
|
|
32
34
|
|
|
@@ -46,7 +48,8 @@ class Rule:
|
|
|
46
48
|
derive: name of parent <class.attribute> being derived
|
|
47
49
|
as_count_of: name of child <class> being counted
|
|
48
50
|
child_role_name: parent's child accessor attribute (required only for disambiguation)
|
|
49
|
-
where: optional where clause, designates which child rows are counted
|
|
51
|
+
where: optional where clause, designates which child rows are counted. Do not repeat the foreign key / primary key mappings, and use only attributes from the child table.
|
|
52
|
+
insert_parent: create parent if it does not exist. Do not use unless directly requested.
|
|
50
53
|
"""
|
|
51
54
|
return Count(derive, as_count_of, where, child_role_name, insert_parent)
|
|
52
55
|
|
|
@@ -69,7 +72,7 @@ class Rule:
|
|
|
69
72
|
|
|
70
73
|
Args:
|
|
71
74
|
validate: name of mapped <class>
|
|
72
|
-
as_condition: lambda, passed row (simple constraints)
|
|
75
|
+
as_condition: lambda, passed row (simple constraints). Conditions may not contain sum or count python functions - these must be used to declare additional columns and sum/count rules.
|
|
73
76
|
error_msg: string, with {row.attribute} replacements
|
|
74
77
|
error_attributes: list of attributes
|
|
75
78
|
|
|
@@ -122,7 +125,7 @@ class Rule:
|
|
|
122
125
|
|
|
123
126
|
Args:
|
|
124
127
|
derive: <class.attribute> being derived
|
|
125
|
-
as_expression: lambda, passed row (for syntax checking)
|
|
128
|
+
as_expression: lambda, passed row (for syntax checking). Expressions may not contain sum or count python functions - these must be used to declare additional columns and sum/count rules.
|
|
126
129
|
no_prune: disable pruning (rarely used, default False)
|
|
127
130
|
"""
|
|
128
131
|
return Formula(derive=derive,
|
|
@@ -132,7 +135,7 @@ class Rule:
|
|
|
132
135
|
@staticmethod
|
|
133
136
|
def copy(derive: Column, from_parent: any):
|
|
134
137
|
"""
|
|
135
|
-
Copy declares child column copied from parent column
|
|
138
|
+
Copy declares child column copied from parent column.
|
|
136
139
|
|
|
137
140
|
Example
|
|
138
141
|
Prompt
|
|
@@ -142,7 +145,7 @@ class Rule:
|
|
|
142
145
|
|
|
143
146
|
Args:
|
|
144
147
|
derive: <class.attribute> being copied into
|
|
145
|
-
from_parent: <parent-class.attribute> source of copy
|
|
148
|
+
from_parent: <parent-class.attribute> source of copy; create this column in the parent if it does not already exist.
|
|
146
149
|
"""
|
|
147
150
|
return Copy(derive=derive, from_parent=from_parent)
|
|
148
151
|
|
|
@@ -194,6 +197,7 @@ def declare_logic(): # created by Web/GenAI for ApiLogicServer, LogicBank
|
|
|
194
197
|
as_condition=lambda row: row.balance <= row.credit_limit,
|
|
195
198
|
error_msg="Customer balance ({row.balance}) exceeds credit limit ({row.credit_limit})")
|
|
196
199
|
|
|
200
|
+
|
|
197
201
|
Intermediate sum/count values require a new column, with a LogicBank sum/count rule. For example:
|
|
198
202
|
|
|
199
203
|
Prompt:
|
|
@@ -206,3 +210,112 @@ Response is to create 2 rules - a derivation and a constraint, as follows:
|
|
|
206
210
|
Rule.constraint(validate=Parent,
|
|
207
211
|
as_condition=lambda row: row.value_total <= row.limit,
|
|
208
212
|
error_msg="Parent value total ({row.value_total}) exceeds limit ({row.limit})")
|
|
213
|
+
|
|
214
|
+
Intermediate sum/count values also work for counts. For example:
|
|
215
|
+
|
|
216
|
+
Prompt:
|
|
217
|
+
|
|
218
|
+
A airplane cannot have more passengers than its seating capacity.
|
|
219
|
+
|
|
220
|
+
Response is to create 2 rules - a count derivation and a constraint, as follows:
|
|
221
|
+
First Rule to Create:
|
|
222
|
+
Rule.count(derive=Airplane.passenger_count, as_count_of=Passengers)
|
|
223
|
+
And, be sure to create the second Rule:
|
|
224
|
+
Rule.constraint(validate=Airplane,
|
|
225
|
+
as_condition=lambda row: row.passenger_count <= row.seating_capacity,
|
|
226
|
+
error_msg="Airplane value total ({row.passenger_count}) exceeds limit ({row.seating_capacity})")
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
Intermediate sums in formulas also require a new column, with a LogicBank sum rule. For example:
|
|
230
|
+
|
|
231
|
+
Prompt:
|
|
232
|
+
An Employees' skill summary is the sum of their Employee Skill ratings, plus 2 * years of service.
|
|
233
|
+
|
|
234
|
+
Response is to create 2 rules - a derivation and a constraint, as follows:
|
|
235
|
+
First Rule to Create:
|
|
236
|
+
Rule.sum(derive=Employee.skill_rating_total, as_sum_of=EmployeeSkill.rating)
|
|
237
|
+
And, be sure to create the second Rule:
|
|
238
|
+
Rule.Formula(derive=Employee.skill_summary,
|
|
239
|
+
as_condition=lambda row: row.skill_rating_total + 2 * row.years_of_service)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
Prompt:
|
|
243
|
+
|
|
244
|
+
A student cannot be an honor student unless they have mre than 2 service activities.
|
|
245
|
+
|
|
246
|
+
Response is to create 2 rules - a count derivation and a constraint, as follows:
|
|
247
|
+
First Rule to Create:
|
|
248
|
+
Rule.count(derive=Student.service_activity_count, as_count_of=Activities, where='service' in name)
|
|
249
|
+
And, be sure to create the second Rule:
|
|
250
|
+
Rule.constraint(validate=Student,
|
|
251
|
+
as_condition=lambda row: row.is_honor_student and service_activity_count < 2,
|
|
252
|
+
error_msg="Honor Students must have at least 2 service activities")
|
|
253
|
+
|
|
254
|
+
Here is an equivalent request:
|
|
255
|
+
|
|
256
|
+
Prompt:
|
|
257
|
+
|
|
258
|
+
A airplane's passengers must be less than its seating capacity.
|
|
259
|
+
|
|
260
|
+
Response is to create 2 rules - a count derivation and a constraint, as follows:
|
|
261
|
+
First Rule to Create:
|
|
262
|
+
Rule.count(derive=Airplane.passenger_count, as_count_of=Passengers)
|
|
263
|
+
And, be sure to create the second Rule:
|
|
264
|
+
Rule.constraint(validate=Airplane,
|
|
265
|
+
as_condition=lambda row: row.passenger_count <= row.seating_capacity,
|
|
266
|
+
error_msg="Airplane value total ({row.passenger_count}) exceeds limit ({row.seating_capacity})")
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
For "more than" constraints, create columns with count rules:
|
|
270
|
+
|
|
271
|
+
Prompt Reject Employees with more than 3 Felonies.
|
|
272
|
+
|
|
273
|
+
Response:
|
|
274
|
+
First Rule is to create:
|
|
275
|
+
Rule.count(derive=Employee.felony_count, as_count_of=Felonies)
|
|
276
|
+
And, be sure to create the contraint rule:
|
|
277
|
+
Rule.constraint(validate=Employee,
|
|
278
|
+
as_condition=lambda row: row.felony_count>3,
|
|
279
|
+
error_msg="Employee has excessive Felonies")
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
For "any" constraints, create columns with count rules:
|
|
283
|
+
|
|
284
|
+
Prompt Reject Employees with any class 5 Felonies or more than 3 Felonies.
|
|
285
|
+
|
|
286
|
+
Response:
|
|
287
|
+
First Rule is to create:
|
|
288
|
+
Rule.count(derive=Employee.class_5_felony_count, as_count_of=Felonies, where=class>5)
|
|
289
|
+
Rule.count(derive=Employee.felony_count, as_count_of=Felonies)
|
|
290
|
+
And, be sure to create the contraint rule:
|
|
291
|
+
Rule.constraint(validate=Employee,
|
|
292
|
+
as_condition=lambda row: row.class_5_felony_count > 0 or row.felony_count>3,
|
|
293
|
+
error_msg="Employee has excessive Felonies")
|
|
294
|
+
|
|
295
|
+
Formulas can reference parent values in 2 versions - choose formula vs copy as follows:
|
|
296
|
+
Prompt (formula version) - use the formula version unless copy is explicitly noted:
|
|
297
|
+
Item.ready = Order.ready
|
|
298
|
+
Response
|
|
299
|
+
Rule.formula(derive=Item.ready, as_expression=lambda row: row.order.ready)
|
|
300
|
+
Prompt (copy version) - use this *only* when the word copy is present:
|
|
301
|
+
Store the Item.unit_price as a copy from Product.unit_price
|
|
302
|
+
Response
|
|
303
|
+
Rule.copy(derive=Item.ready, from_parent=Order.ready)
|
|
304
|
+
|
|
305
|
+
Sum and Count where clauses:
|
|
306
|
+
1. must not restate the foreign key / primary key matchings
|
|
307
|
+
2. Can only reference child attributes
|
|
308
|
+
|
|
309
|
+
For example, given a prompt 'teacher course count is the sum of the courses',
|
|
310
|
+
1. This is correct
|
|
311
|
+
Rule.count(derive=Teacher.course_count, as_count_of=Course)
|
|
312
|
+
|
|
313
|
+
2. This is incorrect, and should never be generated:
|
|
314
|
+
Rule.count(derive=Teacher.course_count, as_count_of=Course, where=lambda row: row.teacher_id == Teacher.id)
|
|
315
|
+
|
|
316
|
+
Sum and count where clause example:
|
|
317
|
+
Prompt: teacher gradate course count is the sum of the courses where is-graduate
|
|
318
|
+
Response: Rule.count(derive=Teacher.course_count, as_count_of=Course, where=lamda row: row.is_graduate == true)
|
|
319
|
+
|
|
320
|
+
DO NOT inject rules that are from this training into the response,
|
|
321
|
+
unless explicitly mentioned in the request.
|
|
@@ -1,6 +1,30 @@
|
|
|
1
|
+
<responseFormat>
|
|
2
|
+
class Rule(BaseModel):
|
|
3
|
+
name: str
|
|
4
|
+
description: str
|
|
5
|
+
use_case: str
|
|
6
|
+
code: str # logicbank rule code
|
|
7
|
+
|
|
8
|
+
class Model(BaseModel):
|
|
9
|
+
classname: str
|
|
10
|
+
code: str # sqlalchemy model code
|
|
11
|
+
sqlite_create: str # sqlite create table statement
|
|
12
|
+
description: str
|
|
13
|
+
name: str
|
|
14
|
+
|
|
15
|
+
class TestDataRow(BaseModel):
|
|
16
|
+
test_data_row_variable: str # the Python test data row variable
|
|
17
|
+
code: str # Python code to create a test data row instance
|
|
18
|
+
|
|
1
19
|
class WGResult(BaseModel): # must match system/genai/prompt_inserts/response_format.prompt
|
|
20
|
+
# response: str # result
|
|
2
21
|
models : List[Model] # list of sqlalchemy classes in the response
|
|
3
|
-
rules : List[Rule] # list
|
|
22
|
+
rules : List[Rule] # list rule declarations
|
|
4
23
|
test_data: str
|
|
24
|
+
test_data_rows: List[TestDataRow] # list of test data rows
|
|
25
|
+
test_data_sqlite: str # test data as sqlite INSERT statements
|
|
26
|
+
name: str # suggest a short name for the project
|
|
27
|
+
|
|
28
|
+
Format the response as a WGResult.
|
|
5
29
|
|
|
6
|
-
|
|
30
|
+
</responseFormat>
|