@kindgi/api 0.1.2 → 0.1.3

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 (88) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +2 -1
  3. package/dist/app.js.map +1 -1
  4. package/dist/cost-binding.d.ts +81 -5
  5. package/dist/cost-binding.d.ts.map +1 -1
  6. package/dist/cost-binding.js +6 -0
  7. package/dist/cost-binding.js.map +1 -1
  8. package/dist/hitl-binding.d.ts +20 -5
  9. package/dist/hitl-binding.d.ts.map +1 -1
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/middleware/auth.d.ts +3 -2
  14. package/dist/middleware/auth.d.ts.map +1 -1
  15. package/dist/middleware/auth.js.map +1 -1
  16. package/dist/middleware/idempotency.d.ts +5 -1
  17. package/dist/middleware/idempotency.d.ts.map +1 -1
  18. package/dist/middleware/idempotency.js +8 -1
  19. package/dist/middleware/idempotency.js.map +1 -1
  20. package/dist/openapi/operations.d.ts.map +1 -1
  21. package/dist/openapi/operations.js +83 -18
  22. package/dist/openapi/operations.js.map +1 -1
  23. package/dist/openapi/schemas.d.ts +18 -0
  24. package/dist/openapi/schemas.d.ts.map +1 -1
  25. package/dist/openapi/schemas.js +202 -7
  26. package/dist/openapi/schemas.js.map +1 -1
  27. package/dist/provenance-binding.d.ts +27 -1
  28. package/dist/provenance-binding.d.ts.map +1 -1
  29. package/dist/provenance-binding.js.map +1 -1
  30. package/dist/reviewer-binding.d.ts +10 -2
  31. package/dist/reviewer-binding.d.ts.map +1 -1
  32. package/dist/reviewer-role.d.ts +13 -0
  33. package/dist/reviewer-role.d.ts.map +1 -0
  34. package/dist/reviewer-role.js +27 -0
  35. package/dist/reviewer-role.js.map +1 -0
  36. package/dist/routes/approvals.d.ts +5 -4
  37. package/dist/routes/approvals.d.ts.map +1 -1
  38. package/dist/routes/approvals.js +52 -16
  39. package/dist/routes/approvals.js.map +1 -1
  40. package/dist/routes/conversations.d.ts +7 -1
  41. package/dist/routes/conversations.d.ts.map +1 -1
  42. package/dist/routes/conversations.js +41 -1
  43. package/dist/routes/conversations.js.map +1 -1
  44. package/dist/routes/cost.d.ts.map +1 -1
  45. package/dist/routes/cost.js +95 -9
  46. package/dist/routes/cost.js.map +1 -1
  47. package/dist/routes/identity.d.ts +7 -0
  48. package/dist/routes/identity.d.ts.map +1 -1
  49. package/dist/routes/identity.js +3 -2
  50. package/dist/routes/identity.js.map +1 -1
  51. package/dist/routes/provenance.d.ts.map +1 -1
  52. package/dist/routes/provenance.js +32 -1
  53. package/dist/routes/provenance.js.map +1 -1
  54. package/dist/routes/runs.d.ts +0 -7
  55. package/dist/routes/runs.d.ts.map +1 -1
  56. package/dist/routes/runs.js +44 -20
  57. package/dist/routes/runs.js.map +1 -1
  58. package/dist/routes/scope-params.d.ts +16 -1
  59. package/dist/routes/scope-params.d.ts.map +1 -1
  60. package/dist/routes/scope-params.js +28 -0
  61. package/dist/routes/scope-params.js.map +1 -1
  62. package/dist/types.d.ts +4 -3
  63. package/dist/types.d.ts.map +1 -1
  64. package/dist/webhook-endpoint-binding.d.ts +11 -0
  65. package/dist/webhook-endpoint-binding.d.ts.map +1 -1
  66. package/dist/webhook-endpoint-binding.js.map +1 -1
  67. package/openapi.json +599 -24
  68. package/package.json +21 -21
  69. package/src/app.ts +5 -1
  70. package/src/cost-binding.ts +96 -5
  71. package/src/hitl-binding.ts +20 -4
  72. package/src/index.ts +3 -0
  73. package/src/middleware/auth.ts +3 -2
  74. package/src/middleware/idempotency.ts +7 -1
  75. package/src/openapi/operations.ts +93 -18
  76. package/src/openapi/schemas.ts +221 -7
  77. package/src/provenance-binding.ts +42 -1
  78. package/src/reviewer-binding.ts +10 -2
  79. package/src/reviewer-role.ts +35 -0
  80. package/src/routes/approvals.ts +70 -19
  81. package/src/routes/conversations.ts +57 -1
  82. package/src/routes/cost.ts +104 -20
  83. package/src/routes/identity.ts +10 -2
  84. package/src/routes/provenance.ts +48 -1
  85. package/src/routes/runs.ts +54 -22
  86. package/src/routes/scope-params.ts +35 -1
  87. package/src/types.ts +4 -3
  88. package/src/webhook-endpoint-binding.ts +11 -0
@@ -77,6 +77,13 @@ const TopLevelQueryParam = {
77
77
  description: 'When true, only runs that are not a child of another run.',
78
78
  schema: { type: 'boolean' },
79
79
  };
80
+ const RunAgentIdQueryParam = {
81
+ name: 'agentId',
82
+ in: 'query',
83
+ required: false,
84
+ description: "Only this agent's turns, at any version. Turns that ran before Kindgi 0.1.3 don't name their agent and aren't matched.",
85
+ schema: { type: 'string', minLength: 1 },
86
+ };
80
87
  const RunIncludeQueryParam = {
81
88
  name: 'include',
82
89
  in: 'query',
@@ -410,16 +417,51 @@ const CostToQueryParam = {
410
417
  name: 'to',
411
418
  in: 'query',
412
419
  required: false,
413
- description: 'ISO 8601 timestamp; records with `occurredAt <= to`. Required on `/v1/cost/aggregate` (or both endpoints omitted for default last-30-days window).',
420
+ description: 'ISO 8601 timestamp; records with `occurredAt < to` (exclusive). Required on `/v1/cost/aggregate` (or both endpoints omitted for default last-30-days window).',
414
421
  schema: { type: 'string', format: 'date-time' },
415
422
  };
416
423
  const CostGroupByQueryParam = {
417
424
  name: 'groupBy',
418
425
  in: 'query',
419
426
  required: true,
420
- description: 'Comma-separated list of dimensions to aggregate over. Each value must be one of `agentId | runId | category | providerId | day | month | tenant | conversationId`. Duplicates collapse.',
427
+ description: "Comma-separated list of dimensions to aggregate over. Each value must be one of `agentId | runId | category | providerId | day | month | tenant | conversationId | model | servedModel | projectId | orgId | rootRunId | flowId`. `model` is the model actually called; `servedModel` the exact version the vendor reported; `orgId` the org of the record's project. Duplicates collapse.",
428
+ schema: { type: 'string' },
429
+ };
430
+ const CostModelQueryParam = {
431
+ name: 'model',
432
+ in: 'query',
433
+ required: false,
434
+ description: 'Filter model calls to this model, the one actually called (exact match).',
421
435
  schema: { type: 'string' },
422
436
  };
437
+ const CostServedModelQueryParam = {
438
+ name: 'servedModel',
439
+ in: 'query',
440
+ required: false,
441
+ description: 'Filter model calls to the exact model version the vendor reported (exact match).',
442
+ schema: { type: 'string' },
443
+ };
444
+ const CostRootRunIdQueryParam = {
445
+ name: 'rootRunId',
446
+ in: 'query',
447
+ required: false,
448
+ description: 'Every record of the run tree whose root is this run: a flow run and the agent turns and sub-flows it started.',
449
+ schema: { type: 'string', format: 'uuid' },
450
+ };
451
+ const CostIncludeDescendantsQueryParam = {
452
+ name: 'includeDescendants',
453
+ in: 'query',
454
+ required: false,
455
+ description: "With `runId`: the run's records and those of every run it started, at any depth. `true` or `false` (default).",
456
+ schema: { type: 'boolean', default: false },
457
+ };
458
+ const CostIncludeQueryParam = {
459
+ name: 'include',
460
+ in: 'query',
461
+ required: false,
462
+ description: "Extra fields, comma-separated. `rawUsage`: each model call's usage object exactly as the vendor reported it.",
463
+ schema: { type: 'string', enum: ['rawUsage'] },
464
+ };
423
465
  const ProviderIdPathParam = {
424
466
  name: 'providerId',
425
467
  in: 'path',
@@ -763,14 +805,17 @@ export const OPERATIONS = [
763
805
  parameters: [
764
806
  LimitQueryParam,
765
807
  CursorQueryParam,
808
+ ScopeKindQueryParam,
809
+ ScopeIdQueryParam,
766
810
  ParentRunIdQueryParam,
767
811
  TopLevelQueryParam,
812
+ RunAgentIdQueryParam,
768
813
  RunIncludeQueryParam,
769
814
  ],
770
815
  responses: {
771
816
  '200': { description: 'Page of runs.', schema: ref('RunCollectionPage') },
772
817
  ...CommonAuthErrors,
773
- '400': ErrorResponse('Malformed cursor or filter.'),
818
+ '400': ErrorResponse('Malformed cursor, filter or scope.'),
774
819
  },
775
820
  },
776
821
  {
@@ -783,6 +828,7 @@ export const OPERATIONS = [
783
828
  security: 'bearer',
784
829
  parameters: [RunIdPathParam],
785
830
  responses: {
831
+ '400': ErrorResponse('`runId` is not a run id (a UUID).'),
786
832
  '200': { description: 'Run row.', schema: ref('Run') },
787
833
  ...CommonAuthErrors,
788
834
  '404': ErrorResponse('No run with that id under this tenant.'),
@@ -831,6 +877,7 @@ export const OPERATIONS = [
831
877
  security: 'bearer',
832
878
  parameters: [RunIdPathParam, JournalSinceQueryParam],
833
879
  responses: {
880
+ '400': ErrorResponse('`runId` is not a run id (a UUID).'),
834
881
  '200': { description: 'Journal page.', schema: ref('RunJournalPage') },
835
882
  ...CommonAuthErrors,
836
883
  '404': ErrorResponse('No run with that id under this tenant.'),
@@ -847,6 +894,7 @@ export const OPERATIONS = [
847
894
  security: 'bearer',
848
895
  parameters: [RunIdPathParam, LastEventIdParam],
849
896
  responses: {
897
+ '400': ErrorResponse('`runId` is not a run id (a UUID).'),
850
898
  '200': {
851
899
  description: 'text/event-stream. Each frame is one RunEvent.',
852
900
  contentType: 'text/event-stream',
@@ -867,6 +915,7 @@ export const OPERATIONS = [
867
915
  security: 'bearer-or-public-run',
868
916
  parameters: [RunIdPathParam],
869
917
  responses: {
918
+ '400': ErrorResponse('`runId` is not a run id (a UUID).'),
870
919
  '200': { description: "The run's progress.", schema: ref('RunProgress') },
871
920
  ...CommonAuthErrors,
872
921
  '404': ErrorResponse('No run with that id that the token may read.'),
@@ -883,6 +932,7 @@ export const OPERATIONS = [
883
932
  security: 'bearer-or-public-run',
884
933
  parameters: [RunIdPathParam, LastEventIdParam],
885
934
  responses: {
935
+ '400': ErrorResponse('`runId` is not a run id (a UUID).'),
886
936
  '200': {
887
937
  description: 'text/event-stream. Each frame is one RunProgressEvent.',
888
938
  contentType: 'text/event-stream',
@@ -1073,12 +1123,14 @@ export const OPERATIONS = [
1073
1123
  openapiPath: '/v1/approvals',
1074
1124
  operationId: 'approvals.list',
1075
1125
  summary: 'List approvals visible to the caller',
1076
- description: 'Requires the token to carry a `reviewerRole`. Role-scoped: reviewers only see approvals whose `requiredRole` rank ≤ their rank (standard < senior < admin).',
1126
+ description: "Requires a reviewer: a token that carries a `reviewerRole`, or whose user is a registered reviewer (the roster gives the role). Role-scoped: reviewers only see approvals whose `requiredRole` rank ≤ their rank (standard < senior < admin). `scopeKind`/`scopeId` narrow to one project's approvals, or every project's in an org; approvals from before Kindgi 0.1.3 have no project and are listed only without a scope.",
1077
1127
  tags: ['approvals'],
1078
1128
  security: 'bearer',
1079
1129
  parameters: [
1080
1130
  LimitQueryParam,
1081
1131
  CursorQueryParam,
1132
+ ScopeKindQueryParam,
1133
+ ScopeIdQueryParam,
1082
1134
  ApprovalStatusQueryParam,
1083
1135
  ApprovalRequiredRoleQueryParam,
1084
1136
  CreatedAfterQueryParam,
@@ -1086,8 +1138,8 @@ export const OPERATIONS = [
1086
1138
  responses: {
1087
1139
  '200': { description: 'Page of approvals.', schema: ref('ApprovalCollectionPage') },
1088
1140
  ...CommonAuthErrors,
1089
- '400': ErrorResponse('Malformed query parameter.'),
1090
- '403': ErrorResponse('Token lacks a reviewer role or asked for a tier above the caller.'),
1141
+ '400': ErrorResponse('Malformed query parameter or scope.'),
1142
+ '403': ErrorResponse("The caller isn't a reviewer, or asked for a tier above its own."),
1091
1143
  },
1092
1144
  },
1093
1145
  {
@@ -1096,14 +1148,14 @@ export const OPERATIONS = [
1096
1148
  openapiPath: '/v1/approvals/{approvalId}',
1097
1149
  operationId: 'approvals.get',
1098
1150
  summary: 'Fetch a single approval',
1099
- description: 'Returns 404 for ids that exist but require a higher role than the caller (avoids cross-tier existence leaks — see API-ROUTE-CONVENTIONS.md §2.4).',
1151
+ description: 'Returns 404 for ids that exist but require a higher role than the caller (avoids cross-tier existence leaks — see API-ROUTE-CONVENTIONS.md §2.4). A decided approval carries its `decision`: what the reviewer decided, why, and who (`decidedBy`, `user:<userId>`).',
1100
1152
  tags: ['approvals'],
1101
1153
  security: 'bearer',
1102
1154
  parameters: [ApprovalIdPathParam],
1103
1155
  responses: {
1104
1156
  '200': { description: 'Approval.', schema: ref('Approval') },
1105
1157
  ...CommonAuthErrors,
1106
- '403': ErrorResponse('Token lacks a reviewer role.'),
1158
+ '403': ErrorResponse("The caller isn't a reviewer."),
1107
1159
  '404': ErrorResponse('No approval with that id — or the caller cannot see it.'),
1108
1160
  },
1109
1161
  },
@@ -1113,7 +1165,7 @@ export const OPERATIONS = [
1113
1165
  openapiPath: '/v1/approvals/{approvalId}/complete',
1114
1166
  operationId: 'approvals.complete',
1115
1167
  summary: 'Submit a decision on an approval',
1116
- description: 'Records the decision (`HitlBinding.submitReview`). When the approval carries a `waitTokenId` and the decision is `approve` or `reject`, also completes the waitpoint so the suspended run resumes.',
1168
+ description: "Records the decision (`HitlBinding.submitReview`). When the approval carries a `waitTokenId` and the decision is `approve` or `reject`, also completes the waitpoint so the suspended run resumes, with `{ decided, rationale?, decidedBy, approvalId }`: the run's journal records who decided which approval (`decidedBy` is `user:<userId>`).",
1117
1169
  tags: ['approvals'],
1118
1170
  security: 'bearer',
1119
1171
  parameters: [ApprovalIdPathParam, IdempotencyKeyParam],
@@ -1206,7 +1258,7 @@ export const OPERATIONS = [
1206
1258
  responses: {
1207
1259
  '200': { description: 'Signed audit bundle.', schema: ref('ExportAuditBundleResult') },
1208
1260
  ...CommonMutationErrors,
1209
- '403': ErrorResponse('Token lacks a reviewer role.'),
1261
+ '403': ErrorResponse("The caller isn't a reviewer."),
1210
1262
  '404': ErrorResponse('Approval not found, signing key id unknown, or signing not configured on this deployment.'),
1211
1263
  },
1212
1264
  },
@@ -1648,12 +1700,14 @@ export const OPERATIONS = [
1648
1700
  openapiPath: '/v1/conversations',
1649
1701
  operationId: 'conversations.list',
1650
1702
  summary: 'List conversations',
1651
- description: 'Cursor-paginated. Fixed sort: `openedAt desc, id desc`. Filters: `?agentId=`, `?status=open|closed`.',
1703
+ description: "Cursor-paginated. Fixed sort: `openedAt desc, id desc`. Filters: `?agentId=`, `?status=open|closed`, and `scopeKind`/`scopeId` for one project's conversations, or every project's in an org. Conversations from before Kindgi 0.1.3 have no project and are listed only without a scope.",
1652
1704
  tags: ['conversations'],
1653
1705
  security: 'bearer',
1654
1706
  parameters: [
1655
1707
  LimitQueryParam,
1656
1708
  CursorQueryParam,
1709
+ ScopeKindQueryParam,
1710
+ ScopeIdQueryParam,
1657
1711
  AgentIdQueryParam,
1658
1712
  ConversationStatusQueryParam,
1659
1713
  ],
@@ -1663,7 +1717,7 @@ export const OPERATIONS = [
1663
1717
  schema: ref('ConversationCollectionPage'),
1664
1718
  },
1665
1719
  ...CommonAuthErrors,
1666
- '400': ErrorResponse('Malformed query parameter.'),
1720
+ '400': ErrorResponse('Malformed query parameter or scope.'),
1667
1721
  },
1668
1722
  },
1669
1723
  {
@@ -1687,7 +1741,7 @@ export const OPERATIONS = [
1687
1741
  openapiPath: '/v1/conversations',
1688
1742
  operationId: 'conversations.open',
1689
1743
  summary: 'Open a conversation',
1690
- description: 'Pins `(agentId, agentVersion)` at open time. `title` defaults to `"Untitled conversation"` when omitted; `scope` accepts arbitrary JSON.',
1744
+ description: 'Pins `(agentId, agentVersion)` at open time. `title` defaults to `"Untitled conversation"` when omitted; `projectId` puts it in a project (lists filter by it; omitted, the Default project); `scope` accepts arbitrary JSON.',
1691
1745
  tags: ['conversations'],
1692
1746
  security: 'bearer',
1693
1747
  parameters: [IdempotencyKeyParam],
@@ -1986,12 +2040,14 @@ export const OPERATIONS = [
1986
2040
  openapiPath: '/v1/provenance',
1987
2041
  operationId: 'provenance.list',
1988
2042
  summary: 'List provenance records',
1989
- description: 'Cursor-paginated. Metadata rows only — clients fetch the DAG payload via `GET /v1/provenance/{runId}`. Fixed sort: `createdAt desc, id desc`. Filters: `?runId=`, `?agentId=`, `?createdAfter=`.',
2043
+ description: "Cursor-paginated. Metadata rows only — clients fetch the DAG payload via `GET /v1/provenance/{runId}`. Fixed sort: `createdAt desc, id desc`. Filters: `?runId=`, `?agentId=`, `?createdAfter=`, and `scopeKind`/`scopeId` for one project's records, or every project's in an org (records from before Kindgi 0.1.3 have no project and are listed only without a scope).",
1990
2044
  tags: ['provenance'],
1991
2045
  security: 'bearer',
1992
2046
  parameters: [
1993
2047
  LimitQueryParam,
1994
2048
  CursorQueryParam,
2049
+ ScopeKindQueryParam,
2050
+ ScopeIdQueryParam,
1995
2051
  ProvenanceRunIdQueryParam,
1996
2052
  ProvenanceAgentIdQueryParam,
1997
2053
  ProvenanceCreatedAfterQueryParam,
@@ -1999,7 +2055,7 @@ export const OPERATIONS = [
1999
2055
  responses: {
2000
2056
  '200': { description: 'Page of records.', schema: ref('ProvenanceCollectionPage') },
2001
2057
  ...CommonAuthErrors,
2002
- '400': ErrorResponse('Malformed cursor or `createdAfter` timestamp.'),
2058
+ '400': ErrorResponse('Malformed cursor, `createdAfter` timestamp or scope.'),
2003
2059
  },
2004
2060
  },
2005
2061
  {
@@ -2473,7 +2529,7 @@ export const OPERATIONS = [
2473
2529
  openapiPath: '/v1/cost/records',
2474
2530
  operationId: 'cost.records.list',
2475
2531
  summary: 'List cost records',
2476
- description: 'Cursor-paginated. Filters (all AND): `runId`, `agentId`, `conversationId`, `category`, `providerId`, `from`, `to`. Sort order is fixed: `occurredAt desc, id desc`. Records represent one accounted resource event each — LLM inference, tool invocation, storage write, sandbox execution, etc.',
2532
+ description: "Cursor-paginated. Filters (all AND): `runId` (with `includeDescendants`, its whole subtree), `rootRunId`, `agentId`, `conversationId`, `category`, `providerId`, `model`, `servedModel`, `from`, `to`. Sort order is fixed: `occurredAt desc, id desc`. Records represent one accounted resource event each — a model call (`category` `llm.inference`: one record per call, with its model, usage and what the vendor said about it), tool invocation, storage write, sandbox execution, etc. `include=rawUsage` adds each model call's usage as the vendor reported it.",
2477
2533
  tags: ['cost'],
2478
2534
  security: 'bearer',
2479
2535
  parameters: [
@@ -2484,11 +2540,16 @@ export const OPERATIONS = [
2484
2540
  CostConversationIdQueryParam,
2485
2541
  CostCategoryQueryParam,
2486
2542
  CostProviderIdQueryParam,
2543
+ CostModelQueryParam,
2544
+ CostServedModelQueryParam,
2545
+ CostRootRunIdQueryParam,
2546
+ CostIncludeDescendantsQueryParam,
2487
2547
  CostFromQueryParam,
2488
2548
  CostToQueryParam,
2489
2549
  ScopeKindQueryParam,
2490
2550
  ScopeIdQueryParam,
2491
2551
  InheritQueryParam,
2552
+ CostIncludeQueryParam,
2492
2553
  ],
2493
2554
  responses: {
2494
2555
  '200': { description: 'Page of cost records.', schema: ref('CostRecordCollectionPage') },
@@ -2504,7 +2565,7 @@ export const OPERATIONS = [
2504
2565
  summary: 'Fetch a cost record',
2505
2566
  tags: ['cost'],
2506
2567
  security: 'bearer',
2507
- parameters: [CostRecordIdPathParam],
2568
+ parameters: [CostRecordIdPathParam, CostIncludeQueryParam],
2508
2569
  responses: {
2509
2570
  '200': { description: 'Cost record.', schema: ref('CostRecord') },
2510
2571
  ...CommonAuthErrors,
@@ -2517,7 +2578,7 @@ export const OPERATIONS = [
2517
2578
  openapiPath: '/v1/cost/aggregate',
2518
2579
  operationId: 'cost.aggregate',
2519
2580
  summary: 'Aggregate cost across a time window',
2520
- description: 'Primary consumer path for dashboards. `groupBy` is required (comma-separated dimensions from the closed set); time range is required (both `from` and `to`, or both omitted for the default last-30-days window echoed back in `timeRange`). Filters compose on top of the time window. `?scopeKind + ?scopeId + ?inherit` narrow the aggregate to a specific scope — reconciles byte-for-byte with the same scoped `/records` list.',
2581
+ description: "Primary consumer path for dashboards. `groupBy` is required (comma-separated dimensions from the closed set); time range is required (both `from` and `to`, or both omitted for the default last-30-days window echoed back in `timeRange`). Filters compose on top of the time window. `?scopeKind + ?scopeId` narrow the aggregate to a scope: `org` covers every project in the org, so one call sums an org's spend. Each group, and the total, carries its cost and its token sums (`tokens`). `inherit` has no effect on cost records, which always belong to a project.",
2521
2582
  tags: ['cost'],
2522
2583
  security: 'bearer',
2523
2584
  parameters: [
@@ -2529,6 +2590,10 @@ export const OPERATIONS = [
2529
2590
  CostAgentIdQueryParam,
2530
2591
  CostRunIdQueryParam,
2531
2592
  CostConversationIdQueryParam,
2593
+ CostModelQueryParam,
2594
+ CostServedModelQueryParam,
2595
+ CostRootRunIdQueryParam,
2596
+ CostIncludeDescendantsQueryParam,
2532
2597
  ScopeKindQueryParam,
2533
2598
  ScopeIdQueryParam,
2534
2599
  InheritQueryParam,