@axiom-lattice/examples-deep_research 1.0.93 → 1.0.94

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @axiom-lattice/examples-deep_research@1.0.93 build /home/runner/work/agentic/agentic/examples/deep_research
2
+ > @axiom-lattice/examples-deep_research@1.0.94 build /home/runner/work/agentic/agentic/examples/deep_research
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -9,9 +9,9 @@
9
9
  CLI Target: es2020
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
- ESM dist/index.js 71.96 KB
13
- ESM dist/index.js.map 88.38 KB
14
- ESM ⚡️ Build success in 96ms
12
+ ESM dist/index.js 78.55 KB
13
+ ESM dist/index.js.map 97.58 KB
14
+ ESM ⚡️ Build success in 98ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 14884ms
16
+ DTS ⚡️ Build success in 13806ms
17
17
  DTS dist/index.d.ts 13.00 B
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @axiom-lattice/examples-deep_research
2
2
 
3
+ ## 1.0.94
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [f5eea72]
8
+ - @axiom-lattice/pg-stores@1.0.75
9
+ - @axiom-lattice/gateway@2.1.96
10
+ - @axiom-lattice/core@2.1.84
11
+
3
12
  ## 1.0.93
4
13
 
5
14
  ### Patch Changes
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ var require_package = __commonJS({
9
9
  "package.json"(exports, module) {
10
10
  module.exports = {
11
11
  name: "@axiom-lattice/examples-deep_research",
12
- version: "1.0.93",
12
+ version: "1.0.94",
13
13
  type: "module",
14
14
  main: "dist/index.js",
15
15
  bin: {
@@ -745,6 +745,46 @@ registerAgentLattices4(tenantId4, [sandboxAgent]);
745
745
  import z4 from "zod";
746
746
  import { registerToolLattice } from "@axiom-lattice/core";
747
747
  var BASE_URL = process.env.SAP_SERVICE_LAYER_URL || "https://b1s.alphafina.cn/b1s/v1";
748
+ var EXPAND_FIELDS = {
749
+ "DocumentLines": [
750
+ "LineNum",
751
+ "ItemCode",
752
+ "ItemDescription",
753
+ "Quantity",
754
+ "UnitPrice",
755
+ "WarehouseCode",
756
+ "Total",
757
+ "Currency",
758
+ "TaxCode",
759
+ "PriceAfterVAT",
760
+ "UoMEntry",
761
+ "UoMCode"
762
+ ],
763
+ "DocumentAdditionalExpenses": [
764
+ "LineNum",
765
+ "ExpenseCode",
766
+ "LineTotal",
767
+ "TaxCode",
768
+ "VatGroup"
769
+ ]
770
+ };
771
+ var ENTITIES_WITH_LINES = /* @__PURE__ */ new Set([
772
+ "Orders",
773
+ "DeliveryNotes",
774
+ "Invoices",
775
+ "Quotations",
776
+ "CreditNotes",
777
+ "Returns",
778
+ "Drafts",
779
+ "PurchaseOrders",
780
+ "PurchaseDeliveryNotes",
781
+ "PurchaseInvoices",
782
+ "PurchaseReturns",
783
+ "PurchaseQuotations",
784
+ "DownPayments",
785
+ "InventoryGenEntries",
786
+ "InventoryGenExits"
787
+ ]);
748
788
  var API_LIST = [
749
789
  // ========== Business Partner ==========
750
790
  {
@@ -769,7 +809,9 @@ var API_LIST = [
769
809
  "SalesPersonCode",
770
810
  "PriceListNum",
771
811
  "CreditLimit",
772
- "Balance",
812
+ "CurrentAccountBalance",
813
+ "OpenOrdersBalance",
814
+ "OpenDeliveryNotesBalance",
773
815
  "PayTermsGrpCode",
774
816
  "VatGroup",
775
817
  "VatLiable",
@@ -778,7 +820,11 @@ var API_LIST = [
778
820
  "Frozen",
779
821
  "CompanyPrivate",
780
822
  "CreateDate",
781
- "UpdateDate"
823
+ "CreateTime",
824
+ "UpdateDate",
825
+ "UpdateTime",
826
+ "BPAddresses",
827
+ "ContactEmployees"
782
828
  ]
783
829
  },
784
830
  {
@@ -829,7 +875,9 @@ var API_LIST = [
829
875
  "Valid",
830
876
  "Frozen",
831
877
  "CreateDate",
832
- "UpdateDate"
878
+ "UpdateDate",
879
+ "ItemPrices",
880
+ "ItemWarehouseInfoCollection"
833
881
  ]
834
882
  },
835
883
  {
@@ -903,7 +951,8 @@ var API_LIST = [
903
951
  "RoundDif",
904
952
  "DiscountPercent",
905
953
  "PaymentGroupCode",
906
- "Project"
954
+ "Project",
955
+ "DocumentLines"
907
956
  ]
908
957
  },
909
958
  {
@@ -929,7 +978,8 @@ var API_LIST = [
929
978
  "Cancelled",
930
979
  "DocumentStatus",
931
980
  "Comments",
932
- "NumAtCard"
981
+ "NumAtCard",
982
+ "DocumentLines"
933
983
  ]
934
984
  },
935
985
  {
@@ -956,7 +1006,8 @@ var API_LIST = [
956
1006
  "DocumentStatus",
957
1007
  "Comments",
958
1008
  "NumAtCard",
959
- "VatSum"
1009
+ "VatSum",
1010
+ "DocumentLines"
960
1011
  ]
961
1012
  },
962
1013
  {
@@ -978,7 +1029,8 @@ var API_LIST = [
978
1029
  "DocCurrency",
979
1030
  "SalesPersonCode",
980
1031
  "Comments",
981
- "DocumentStatus"
1032
+ "DocumentStatus",
1033
+ "DocumentLines"
982
1034
  ]
983
1035
  },
984
1036
  {
@@ -997,7 +1049,8 @@ var API_LIST = [
997
1049
  "CardName",
998
1050
  "DocTotal",
999
1051
  "DocCurrency",
1000
- "Comments"
1052
+ "Comments",
1053
+ "DocumentLines"
1001
1054
  ]
1002
1055
  },
1003
1056
  {
@@ -1016,7 +1069,8 @@ var API_LIST = [
1016
1069
  "CardName",
1017
1070
  "DocTotal",
1018
1071
  "DocCurrency",
1019
- "Comments"
1072
+ "Comments",
1073
+ "DocumentLines"
1020
1074
  ]
1021
1075
  },
1022
1076
  {
@@ -1036,7 +1090,8 @@ var API_LIST = [
1036
1090
  "DocTotal",
1037
1091
  "DocCurrency",
1038
1092
  "DownPaymentType",
1039
- "DownPaymentAmount"
1093
+ "DownPaymentAmount",
1094
+ "DocumentLines"
1040
1095
  ]
1041
1096
  },
1042
1097
  {
@@ -1092,7 +1147,8 @@ var API_LIST = [
1092
1147
  "Cancelled",
1093
1148
  "DocumentStatus",
1094
1149
  "Comments",
1095
- "NumAtCard"
1150
+ "NumAtCard",
1151
+ "DocumentLines"
1096
1152
  ]
1097
1153
  },
1098
1154
  {
@@ -1110,7 +1166,8 @@ var API_LIST = [
1110
1166
  "CardCode",
1111
1167
  "CardName",
1112
1168
  "DocTotal",
1113
- "Comments"
1169
+ "Comments",
1170
+ "DocumentLines"
1114
1171
  ]
1115
1172
  },
1116
1173
  {
@@ -1130,7 +1187,8 @@ var API_LIST = [
1130
1187
  "CardName",
1131
1188
  "DocTotal",
1132
1189
  "DocCurrency",
1133
- "Comments"
1190
+ "Comments",
1191
+ "DocumentLines"
1134
1192
  ]
1135
1193
  },
1136
1194
  {
@@ -1148,7 +1206,8 @@ var API_LIST = [
1148
1206
  "CardCode",
1149
1207
  "CardName",
1150
1208
  "DocTotal",
1151
- "Comments"
1209
+ "Comments",
1210
+ "DocumentLines"
1152
1211
  ]
1153
1212
  },
1154
1213
  {
@@ -1166,7 +1225,8 @@ var API_LIST = [
1166
1225
  "CardCode",
1167
1226
  "CardName",
1168
1227
  "DocTotal",
1169
- "Comments"
1228
+ "Comments",
1229
+ "DocumentLines"
1170
1230
  ]
1171
1231
  },
1172
1232
  // ========== Inventory / Warehouse ==========
@@ -1186,7 +1246,8 @@ var API_LIST = [
1186
1246
  "JournalMemo",
1187
1247
  "Reference1",
1188
1248
  "Reference2",
1189
- "WareHouseUpdateType"
1249
+ "WareHouseUpdateType",
1250
+ "DocumentLines"
1190
1251
  ]
1191
1252
  },
1192
1253
  {
@@ -1204,7 +1265,8 @@ var API_LIST = [
1204
1265
  "Comments",
1205
1266
  "JournalMemo",
1206
1267
  "Reference1",
1207
- "Reference2"
1268
+ "Reference2",
1269
+ "DocumentLines"
1208
1270
  ]
1209
1271
  },
1210
1272
  {
@@ -1555,25 +1617,49 @@ var API_LIST = [
1555
1617
  ]
1556
1618
  }
1557
1619
  ];
1620
+ function mapResult(e) {
1621
+ const r = {
1622
+ name: e.name,
1623
+ kind: e.kind,
1624
+ domain: e.domain,
1625
+ description: e.description,
1626
+ primaryKey: e.primaryKey || null,
1627
+ fields: e.fields,
1628
+ readySelect: e.fields.length > 0 ? `$select=${e.fields.join(",")}` : void 0,
1629
+ hint: e.kind === "EntitySet" ? `${e.name} \u2014 ${e.description}\u3002\u4E3B\u952E: ${e.primaryKey}\u3002\u8C03\u7528 sap_api_call \u8FDB\u884C CRUD \u64CD\u4F5C\u3002` : `${e.name} \u2014 ${e.description}\u3002\u8C03\u7528 sap_api_call \u6267\u884C\u6B64\u65B9\u6CD5\u3002`
1630
+ };
1631
+ if (ENTITIES_WITH_LINES.has(e.name)) {
1632
+ r.expand = ["DocumentLines", "DocumentAdditionalExpenses"];
1633
+ r.lineFields = ["LineNum", "ItemCode", "ItemDescription", "Quantity", "UnitPrice", "Price", "WarehouseCode", "UoMEntry", "UoMCode", "VatGroup", "Currency", "TaxCode", "PriceAfterVAT"];
1634
+ }
1635
+ if (e.name === "Items") {
1636
+ r.expand = ["ItemPrices", "ItemWarehouseInfoCollection"];
1637
+ }
1638
+ if (e.name === "BusinessPartners") {
1639
+ r.expand = ["BPAddresses", "ContactEmployees"];
1640
+ }
1641
+ return r;
1642
+ }
1558
1643
  registerToolLattice(
1559
1644
  "sap_api_search",
1560
1645
  {
1561
1646
  name: "sap_api_search",
1562
- description: "\u641C\u7D22 SAP B1 Service Layer API \u63A5\u53E3\u3002\u8986\u76D6\u4E1A\u52A1\u4F19\u4F34(BP)\u3001\u7269\u6599(Item)\u3001\u9500\u552E/\u91C7\u8D2D\u8BA2\u5355(Document/Order)\u3001\u5E93\u5B58(Inventory/Warehouse) \u56DB\u5927\u9886\u57DF\u3002\u8FD4\u56DE\u63A5\u53E3\u540D\u79F0\u3001\u4E3B\u952E\u3001\u5E38\u7528\u5B57\u6BB5\u5217\u8868\u53CA\u63CF\u8FF0\u3002",
1647
+ description: "\u641C\u7D22 SAP B1 Service Layer API \u63A5\u53E3\u5143\u6570\u636E\uFF0C\u8986\u76D6 BP/\u7269\u6599/\u8BA2\u5355/\u5E93\u5B58\u56DB\u5927\u9886\u57DF\u3002\u8FD4\u56DE\u63A5\u53E3\u540D\u3001\u4E3B\u952E\u3001\u5B57\u6BB5\u5217\u8868\u3001\u53EF\u9009 expand \u5BFC\u822A\u3002\u53EF\u7528 discover \u6A21\u5F0F\u53D1\u73B0\u5173\u8054\u63A5\u53E3\uFF08\u5982\u641C SalesPerson \u4E5F\u80FD\u627E\u5230 SalesPersons API\uFF09\u3002\u641C\u7D22\u7ED3\u679C\u4E2D\u7684 readySelect \u53EF\u76F4\u63A5\u590D\u5236\u5230 $select\u3002",
1563
1648
  needUserApprove: false,
1564
1649
  schema: z4.object({
1565
- query: z4.string().describe(
1566
- "\u641C\u7D22\u5173\u952E\u8BCD\u3002\u53EF\u4EE5\u662F API \u540D\u79F0\uFF08\u5982 'BusinessPartners', 'Orders', 'Items', 'PurchaseOrders'\uFF09\u6216\u4E1A\u52A1\u63CF\u8FF0\uFF08\u5982 '\u5BA2\u6237', '\u8BA2\u5355', '\u7269\u6599', '\u5E93\u5B58', '\u91C7\u8D2D', '\u4ED3\u5E93'\uFF09"
1650
+ query: z4.string().optional().describe(
1651
+ "\u641C\u7D22\u5173\u952E\u8BCD\uFF08\u53EF\u9009\uFF0C\u4E0D\u4F20\u5219\u8FD4\u56DE\u5168\u90E8\u63A5\u53E3\uFF09\u3002API \u540D\u79F0\u5982 'BusinessPartners', 'Orders', 'Items', 'PurchaseOrders'\uFF0C\u6216\u4E2D\u6587\u63CF\u8FF0\u5982 '\u5BA2\u6237', '\u8BA2\u5355', '\u7269\u6599', '\u5E93\u5B58', '\u91C7\u8D2D', '\u4ED3\u5E93'"
1567
1652
  ),
1568
1653
  domain: z4.string().optional().describe(
1569
1654
  "\u6309\u9886\u57DF\u8FC7\u6EE4: 'BusinessPartner'(BP), 'Item / Product'(\u7269\u6599), 'Document'(\u8BA2\u5355/\u53D1\u7968), 'Inventory / Warehouse'(\u5E93\u5B58/\u4ED3\u5E93)"
1570
1655
  ),
1571
- maxResults: z4.number().optional().default(10).describe("\u6700\u5927\u8FD4\u56DE\u6761\u6570")
1656
+ maxResults: z4.number().optional().default(20).describe("\u6700\u5927\u8FD4\u56DE\u6761\u6570")
1572
1657
  })
1573
1658
  },
1574
1659
  async (input) => {
1575
- const q = input.query.toLowerCase();
1576
- const max = input.maxResults ?? 10;
1660
+ const q = input.query?.toLowerCase();
1661
+ const max = input.maxResults ?? 20;
1662
+ const hasQuery = q && q.trim().length > 0;
1577
1663
  const domainHints = {
1578
1664
  "\u5BA2\u6237": "BusinessPartner",
1579
1665
  "\u4F9B\u5E94\u5546": "BusinessPartner",
@@ -1589,6 +1675,8 @@ registerToolLattice(
1589
1675
  "\u4EA4\u8D27": "Document",
1590
1676
  "\u62A5\u4EF7": "Document",
1591
1677
  "\u8349\u7A3F": "Document",
1678
+ "draft": "Document",
1679
+ "\u6682\u5B58": "Document",
1592
1680
  "\u5E93\u5B58": "Inventory / Warehouse",
1593
1681
  "\u4ED3\u5E93": "Inventory / Warehouse",
1594
1682
  "\u5E93\u4F4D": "Inventory / Warehouse",
@@ -1604,12 +1692,26 @@ registerToolLattice(
1604
1692
  "\u6C47\u7387": "Finance / Accounting",
1605
1693
  "\u5230\u5CB8": "Document"
1606
1694
  };
1607
- const hintedDomain = domainHints[q] || void 0;
1695
+ const hintedDomain = q ? domainHints[q] || void 0 : void 0;
1608
1696
  const effectiveDomain = input.domain || hintedDomain;
1609
- const scored = API_LIST.filter((e) => {
1697
+ const filtered = API_LIST.filter((e) => {
1610
1698
  if (effectiveDomain && e.domain !== effectiveDomain) return false;
1611
1699
  return true;
1612
- }).map((e) => {
1700
+ });
1701
+ if (!q) {
1702
+ const top2 = filtered.slice(0, max);
1703
+ const domainCounts2 = {};
1704
+ for (const e of top2) domainCounts2[e.domain] = (domainCounts2[e.domain] || 0) + 1;
1705
+ return {
1706
+ query: input.query || null,
1707
+ domainFilter: effectiveDomain || null,
1708
+ totalMatches: filtered.length,
1709
+ domainsFound: domainCounts2,
1710
+ results: top2.map(mapResult),
1711
+ suggestion: void 0
1712
+ };
1713
+ }
1714
+ const scored = filtered.map((e) => {
1613
1715
  let score = 0;
1614
1716
  const nameLo = e.name.toLowerCase();
1615
1717
  const descLo = e.description.toLowerCase();
@@ -1633,15 +1735,7 @@ registerToolLattice(
1633
1735
  domainFilter: effectiveDomain || null,
1634
1736
  totalMatches: scored.filter((e) => e.score > 0).length,
1635
1737
  domainsFound: domainCounts,
1636
- results: top.map((e) => ({
1637
- name: e.name,
1638
- kind: e.kind,
1639
- domain: e.domain,
1640
- description: e.description,
1641
- primaryKey: e.primaryKey || null,
1642
- fields: e.fields,
1643
- hint: e.kind === "EntitySet" ? `${e.name} \u2014 ${e.description}\u3002\u4E3B\u952E: ${e.primaryKey}\u3002\u8C03\u7528 sap_api_call \u8FDB\u884C CRUD \u64CD\u4F5C\u3002` : `${e.name} \u2014 ${e.description}\u3002\u8C03\u7528 sap_api_call \u6267\u884C\u6B64\u65B9\u6CD5\u3002`
1644
- })),
1738
+ results: top.map(mapResult),
1645
1739
  suggestion: top.length === 0 ? `\u672A\u627E\u5230\u5339\u914D "${input.query}" \u7684\u63A5\u53E3\u3002\u53EF\u7528\u9886\u57DF: BusinessPartner(\u5BA2\u6237/\u4F9B\u5E94\u5546), Item / Product(\u7269\u6599), Document(\u8BA2\u5355/\u53D1\u7968), Inventory / Warehouse(\u5E93\u5B58/\u4ED3\u5E93)\u3002\u5C1D\u8BD5\u7528\u82F1\u6587\u540D\u79F0\u641C\u7D22\u3002` : void 0
1646
1740
  };
1647
1741
  }
@@ -1651,20 +1745,32 @@ registerToolLattice(
1651
1745
  "sap_api_call",
1652
1746
  {
1653
1747
  name: "sap_api_call",
1654
- description: `\u6267\u884C\u5BF9 SAP B1 Service Layer \u7684 OData API \u8C03\u7528\u3002\u76F4\u63A5\u53D1\u8D77 HTTP \u8BF7\u6C42\u5E76\u8FD4\u56DE\u54CD\u5E94\u6570\u636E\u3002\u5F53\u524D Base URL: ${BASE_URL}\u3002GET \u8BF7\u6C42\u901A\u5E38\u65E0\u9700\u8BA4\u8BC1\uFF0CPOST/PATCH/DELETE \u9700\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF SAP_B1SESSION\u3002`,
1748
+ description: `\u6267\u884C SAP B1 Service Layer \u7684 OData API \u67E5\u8BE2/\u521B\u5EFA/\u66F4\u65B0/\u5220\u9664\u3002Base: ${BASE_URL}\u3002\u26A0\uFE0F \u5148\u786E\u8BA4\u662F\u5426\u5DF2\u901A\u8FC7 sap_api_search \u67E5\u8FC7\u5B57\u6BB5\u5217\u8868\uFF0C\u52FF\u51ED\u8BB0\u5FC6\u7F16\u5B57\u6BB5\u540D\u3002
1749
+ \u26A0\uFE0F \u8349\u7A3F/draft/\u6682\u5B58 \u2192 \u7528 Drafts \u63A5\u53E3\uFF0C\u4E0D\u662F Orders/Invoices \u7B49\u6B63\u5F0F\u5355\u636E\u3002Drafts \u901A\u8FC7 DocObjectCode \u533A\u5206\u5355\u636E\u7C7B\u578B(17=\u8BA2\u5355,13=\u53D1\u7968,16=\u4EA4\u8D27\u5355,23=\u91C7\u8D2D\u8BA2\u5355)\u3002
1750
+ $filter \u64CD\u4F5C\u7B26: eq/ne/gt/lt/ge/le/contains(f,'v')/startswith(f,'v')/endswith(f,'v')\uFF0C\u591A\u6761\u4EF6\u7528 and/or\u3002\u5B57\u7B26\u4E32\u503C\u5FC5\u987B\u5355\u5F15\u53F7\u5305\u88F9\u3002$orderby=Field desc \u6392\u5E8F\u3002
1751
+
1752
+ \u26A0\uFE0F SAP B1 \u5B9E\u6218\u7ECF\u9A8C:
1753
+ 1. \u4E0D\u8981\u7528 $expand\uFF01$expand \u6781\u6613\u89E6\u53D1 400/500\u3002\u6539\u7528 $select \u5305\u542B\u5D4C\u5957\u5B57\u6BB5\uFF0C\u5982 $select=DocEntry,DocNum,DocumentLines\uFF0C
1754
+ DocumentLines \u4F1A\u81EA\u52A8\u4F5C\u4E3A\u5D4C\u5957 JSON \u8FD4\u56DE\u3002ItemPrices\u3001BPAddresses \u7B49\u540C\u7406\u3002
1755
+ 2. \u4E0D\u8981\u7528\u4E3B\u952E\u8DEF\u5F84 /Orders('1173')\uFF0C\u6613 500\u3002\u7528 $filter=DocEntry eq 1173 \u4EE3\u66FF\u3002
1756
+ 3. \u67E5\u5355\u6761\u8BB0\u5F55\u65F6\u4F18\u5148 $filter\uFF0C\u800C\u975E\u4F20 id \u53C2\u6570\u3002
1757
+ 400 \u591A\u4E3A\u7279\u6B8A\u5B57\u7B26\u672A\u7F16\u7801(\u5F15\u53F7\u7528 %27)\uFF1B500 \u591A\u4E3A\u5B57\u6BB5\u4E0D\u5B58\u5728\u6216\u7528\u9519\u4E86 $expand\uFF1B\u65E0\u7ED3\u679C\u5219\u653E\u5BBD filter\u3002
1758
+ POST \u521B\u5EFA: sap_api_search \u8FD4\u56DE\u7684 lineFields \u662F DocumentLines \u5B50\u5B57\u6BB5\u3002body \u5FC5\u542B DocObjectCode(DocType)\u3001CardCode\u3001DocDate\uFF1BDocumentLines \u4E3A\u6570\u7EC4\uFF0C\u6BCF\u9879\u5FC5\u542B ItemCode\u3001Quantity\u3002PATCH \u53EA\u4F20\u53D8\u66F4\u5B57\u6BB5\uFF1BDELETE \u9700\u4F20 id\u3002
1759
+ GET \u81EA\u52A8\u6CE8\u5165 $select+$top=20\uFF0C\u624B\u52A8\u4F20\u5165\u53EF\u8986\u76D6\u3002\u5D4C\u5957\u96C6\u5408(DocumentLines\u7B49)\u81EA\u52A8\u88C1\u526A\u53EA\u4FDD\u7559\u5E38\u7528\u5B57\u6BB5\uFF0C\u9632 token \u7206\u70B8\u3002\u8BA4\u8BC1\u9700 SAP_B1SESSION \u73AF\u5883\u53D8\u91CF\u3002`,
1655
1760
  needUserApprove: false,
1656
1761
  schema: z4.object({
1657
1762
  entitySet: z4.string().describe("EntitySet \u540D\u79F0\uFF0C\u5982 'BusinessPartners', 'Orders', 'Items', 'PurchaseOrders'"),
1658
1763
  method: z4.enum(["GET", "POST", "PATCH", "DELETE"]).describe("HTTP \u65B9\u6CD5"),
1659
1764
  id: z4.string().optional().describe("\u4E3B\u952E\u503C\uFF0CGET/PATCH/DELETE \u5355\u4E2A\u5B9E\u4F53\u65F6\u4F7F\u7528\u3002\u5982 /BusinessPartners('C001')"),
1660
1765
  queryOptions: z4.string().optional().describe(
1661
- "OData \u67E5\u8BE2\u53C2\u6570\uFF08\u4E0D\u542B `?` \u524D\u7F00\uFF09\u3002\u5E38\u7528: $top=10, $skip=20, $select=CardCode,CardName, $filter=contains(CardName,'\u6E05\u534E'), $orderby=DocDate desc, $expand=DocumentLines"
1766
+ "OData \u67E5\u8BE2\u53C2\u6570\uFF08\u4E0D\u542B `?` \u524D\u7F00\uFF09\u3002\u5E38\u7528: $top=10, $select=CardCode,CardName, $filter=CardName eq 'xxx' or contains(CardName,'xxx'), $orderby=DocDate desc, $expand=DocumentLines\u3002\u5B57\u7B26\u4E32\u503C\u7528\u5355\u5F15\u53F7\u3002sap_api_search \u8FD4\u56DE\u7684 readySelect \u53EF\u76F4\u63A5\u590D\u5236\u5230 $select\u3002"
1662
1767
  ),
1663
1768
  body: z4.record(z4.unknown()).optional().describe("POST/PATCH \u65F6\u7684 JSON \u8BF7\u6C42\u4F53")
1664
1769
  })
1665
1770
  },
1666
1771
  async (input) => {
1667
- const url = buildUrl(input.entitySet, input.method, input.id, input.queryOptions);
1772
+ const queryOptions = applyDefaultSelect(input.entitySet, input.method, input.id, input.queryOptions);
1773
+ const url = buildUrl(input.entitySet, input.method, input.id, queryOptions);
1668
1774
  const method = input.method;
1669
1775
  const headers = {
1670
1776
  "Content-Type": "application/json",
@@ -1677,13 +1783,15 @@ registerToolLattice(
1677
1783
  }
1678
1784
  try {
1679
1785
  const res = await fetch(url, fetchOptions);
1680
- const text = await res.text();
1786
+ const buffer = await res.arrayBuffer();
1787
+ const text = new TextDecoder("utf-8", { fatal: false }).decode(buffer);
1681
1788
  let data;
1682
1789
  try {
1683
1790
  data = JSON.parse(text);
1684
1791
  } catch {
1685
1792
  data = text;
1686
1793
  }
1794
+ cleanODataNoise(data);
1687
1795
  const result = {
1688
1796
  ok: res.ok,
1689
1797
  status: res.status,
@@ -1706,6 +1814,63 @@ registerToolLattice(
1706
1814
  }
1707
1815
  }
1708
1816
  );
1817
+ function applyDefaultSelect(entitySet, method, id, queryOptions) {
1818
+ if (method !== "GET") return queryOptions;
1819
+ const parts = [];
1820
+ if (!id && (!queryOptions || !/\$top\s*=/.test(queryOptions))) {
1821
+ parts.push("$top=20");
1822
+ }
1823
+ if (!queryOptions || !/\$select\s*=/.test(queryOptions)) {
1824
+ const entry = API_LIST.find(
1825
+ (e) => e.kind === "EntitySet" && e.name === entitySet
1826
+ );
1827
+ if (entry && entry.fields.length > 0) {
1828
+ parts.push(`$select=${entry.fields.join(",")}`);
1829
+ }
1830
+ }
1831
+ if (queryOptions) {
1832
+ parts.push(queryOptions);
1833
+ }
1834
+ return parts.length > 0 ? parts.join("&").replace(/'/g, "%27") : void 0;
1835
+ }
1836
+ function cleanODataNoise(data) {
1837
+ if (!data || typeof data !== "object") return;
1838
+ if (Array.isArray(data)) {
1839
+ for (const item of data) cleanODataNoise(item);
1840
+ return;
1841
+ }
1842
+ const obj = data;
1843
+ delete obj["odata.metadata"];
1844
+ delete obj["odata.etag"];
1845
+ delete obj["odata.nextLink"];
1846
+ if (Array.isArray(obj.value)) {
1847
+ for (const record of obj.value) {
1848
+ if (record && typeof record === "object") {
1849
+ trimNestedCollections(record);
1850
+ delete record["odata.etag"];
1851
+ }
1852
+ }
1853
+ }
1854
+ for (const v of Object.values(obj)) {
1855
+ if (v && typeof v === "object") cleanODataNoise(v);
1856
+ }
1857
+ }
1858
+ function trimNestedCollections(obj) {
1859
+ for (const [key, val] of Object.entries(obj)) {
1860
+ if (Array.isArray(val) && EXPAND_FIELDS[key]) {
1861
+ const keep = new Set(EXPAND_FIELDS[key]);
1862
+ for (const item of val) {
1863
+ if (item && typeof item === "object") {
1864
+ const record = item;
1865
+ for (const k of Object.keys(record)) {
1866
+ if (!keep.has(k)) delete record[k];
1867
+ }
1868
+ cleanODataNoise(item);
1869
+ }
1870
+ }
1871
+ }
1872
+ }
1873
+ }
1709
1874
  function buildUrl(entitySet, method, id, queryOptions) {
1710
1875
  let url = `${BASE_URL}/${entitySet}`;
1711
1876
  if (id && method !== "POST") {