@4djs/assistant 0.1.5 → 0.1.7

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.
package/dist/labels.d.ts CHANGED
@@ -111,6 +111,8 @@ export declare const DEFAULT_ASSISTANT_LABELS: {
111
111
  readonly "emptyState.capabilities.query": "Query";
112
112
  readonly "emptyState.capabilities.mutate": "Mutate";
113
113
  readonly "activity.trace": "Trace";
114
+ readonly "activity.copyTrace": "Copy trace";
115
+ readonly "activity.copyTraceSuccess": "Trace copied";
114
116
  readonly "activity.live": "Live";
115
117
  readonly "activity.arguments": "Arguments";
116
118
  readonly "activity.running": "Running…";
@@ -1 +1 @@
1
- {"version":3,"file":"labels.d.ts","sourceRoot":"","sources":["../src/labels.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8J3B,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;AAEhE,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAE/D,eAAO,MAAM,oBAAoB,EAE5B,iBAAiB,EAAE,CAAC;AAEzB,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACtC,MAAM,CAIR;AAED,wBAAgB,sBAAsB,CACpC,SAAS,CAAC,EAAE,uBAAuB,GAClC,eAAe,CAEjB"}
1
+ {"version":3,"file":"labels.d.ts","sourceRoot":"","sources":["../src/labels.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgK3B,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;AAEhE,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAE/D,eAAO,MAAM,oBAAoB,EAE5B,iBAAiB,EAAE,CAAC;AAEzB,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACtC,MAAM,CAIR;AAED,wBAAgB,sBAAsB,CACpC,SAAS,CAAC,EAAE,uBAAuB,GAClC,eAAe,CAEjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChatActivity.d.ts","sourceRoot":"","sources":["../../../../src/react/components/chat/ChatActivity.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAKtB,MAAM,gCAAgC,CAAC;AAOxC,UAAU,iBAAiB;IACzB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAyOD,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,iBAAiB,sCAgEnE"}
1
+ {"version":3,"file":"ChatActivity.d.ts","sourceRoot":"","sources":["../../../../src/react/components/chat/ChatActivity.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAMtB,MAAM,gCAAgC,CAAC;AAOxC,UAAU,iBAAiB;IACzB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAkRD,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,iBAAiB,sCAiEnE"}
package/dist/styles.css CHANGED
@@ -808,6 +808,30 @@
808
808
  font-variant-numeric: tabular-nums;
809
809
  }
810
810
 
811
+ .assistant-activity__copy {
812
+ display: inline-flex;
813
+ flex-shrink: 0;
814
+ align-items: center;
815
+ justify-content: center;
816
+ width: 1.625rem;
817
+ height: 1.625rem;
818
+ border: 1px solid var(--border-default);
819
+ border-radius: calc(var(--radius-base) - 2px);
820
+ background: var(--surface-panel);
821
+ color: var(--text-chat-secondary);
822
+ cursor: pointer;
823
+ transition:
824
+ background 150ms ease,
825
+ border-color 150ms ease,
826
+ color 150ms ease;
827
+ }
828
+
829
+ .assistant-activity__copy:hover {
830
+ border-color: var(--border-default-medium);
831
+ background: var(--overlay-subtle);
832
+ color: var(--text-heading);
833
+ }
834
+
811
835
  .assistant-activity__steps {
812
836
  list-style: none;
813
837
  margin: 0;
@@ -1,4 +1,6 @@
1
1
  export { type AssistantToolHandler, type AssistantToolRegistry, connectExternalTools, createAssistantToolRegistry, resolveAssistantToolHooks, } from "../core/tool-registry.js";
2
2
  export type { DatastoreQueryInput, DatastoreToolsAdapter, } from "./datastore.js";
3
3
  export { registerDatastoreTools } from "./datastore.js";
4
+ export { type MethodArgumentSchema, type MethodArgumentType, METHOD_ARGUMENT_TYPES, argumentsToParamsSchema, buildParamsPropertySchema, isMethodArgumentSchema, methodArgumentItemJsonSchema, methodArgumentsEditorJsonSchema, migrateParamsSchemaToArguments, parseMethodArguments, sanitizeMethodArgumentForType, } from "./method-arguments.js";
5
+ export { type BuildMethodToolHandlersOptions, type MethodToolCatalog, type MethodToolInvokeFn, type MethodToolInvokeInput, type MethodToolMetadata, type MethodToolMetadataSchema, type MethodToolScope, buildMethodToolHandlers, buildMethodToolName, } from "./method-tools.js";
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,EACtB,4BAA4B,EAC5B,+BAA+B,EAC/B,8BAA8B,EAC9B,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,8BAA8B,EACnC,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC"}
@@ -43,6 +43,9 @@ class AssistantToolRegistryImpl {
43
43
  has(name) {
44
44
  return this.entries.has(name);
45
45
  }
46
+ listRegisteredToolNames() {
47
+ return [...this.entries.keys()];
48
+ }
46
49
  async listTools() {
47
50
  return [...this.entries.values()].filter((entry) => entry.active).map((entry) => entry.handler.definition);
48
51
  }
@@ -240,9 +243,416 @@ function registerDatastoreTools(registry, adapter) {
240
243
  }
241
244
  return registry;
242
245
  }
246
+ // src/tools/method-arguments.ts
247
+ var METHOD_ARGUMENT_TYPES = [
248
+ "string",
249
+ "integer",
250
+ "number",
251
+ "boolean",
252
+ "object",
253
+ "array"
254
+ ];
255
+ var DESCRIPTION_PROPERTY = {
256
+ type: "string",
257
+ description: "Human-readable description for the assistant"
258
+ };
259
+ var ENUM_PROPERTY = {
260
+ type: "array",
261
+ description: "Allowed values for this parameter",
262
+ items: {}
263
+ };
264
+ var EXAMPLES_PROPERTY = {
265
+ type: "array",
266
+ description: "Example values for this parameter",
267
+ items: {}
268
+ };
269
+ var JSON_SCHEMA_FRAGMENT = {
270
+ type: "object",
271
+ description: "Nested JSON Schema",
272
+ additionalProperties: true
273
+ };
274
+ function argumentTypeBranch(type, typeProperties) {
275
+ return {
276
+ type: "object",
277
+ required: ["type"],
278
+ properties: {
279
+ type: { const: type },
280
+ description: DESCRIPTION_PROPERTY,
281
+ enum: ENUM_PROPERTY,
282
+ examples: EXAMPLES_PROPERTY,
283
+ ...typeProperties
284
+ },
285
+ additionalProperties: true
286
+ };
287
+ }
288
+ var methodArgumentItemJsonSchema = {
289
+ oneOf: [
290
+ argumentTypeBranch("string", {
291
+ minLength: {
292
+ type: "integer",
293
+ minimum: 0,
294
+ description: "Minimum string length"
295
+ },
296
+ maxLength: {
297
+ type: "integer",
298
+ minimum: 0,
299
+ description: "Maximum string length"
300
+ },
301
+ pattern: {
302
+ type: "string",
303
+ description: "Regular expression the string must match"
304
+ }
305
+ }),
306
+ argumentTypeBranch("integer", {
307
+ minimum: {
308
+ type: "number",
309
+ description: "Minimum value (inclusive)"
310
+ },
311
+ maximum: {
312
+ type: "number",
313
+ description: "Maximum value (inclusive)"
314
+ }
315
+ }),
316
+ argumentTypeBranch("number", {
317
+ minimum: {
318
+ type: "number",
319
+ description: "Minimum value (inclusive)"
320
+ },
321
+ maximum: {
322
+ type: "number",
323
+ description: "Maximum value (inclusive)"
324
+ }
325
+ }),
326
+ argumentTypeBranch("boolean", {}),
327
+ argumentTypeBranch("object", {
328
+ properties: {
329
+ type: "object",
330
+ description: "Property schemas keyed by name",
331
+ additionalProperties: JSON_SCHEMA_FRAGMENT
332
+ },
333
+ required: {
334
+ type: "array",
335
+ description: "Required property names",
336
+ items: { type: "string" }
337
+ },
338
+ additionalProperties: {
339
+ description: "Whether properties not listed in properties are allowed",
340
+ type: ["boolean", "object"]
341
+ }
342
+ }),
343
+ argumentTypeBranch("array", {
344
+ items: {
345
+ ...JSON_SCHEMA_FRAGMENT,
346
+ description: "JSON Schema describing each array element"
347
+ },
348
+ minItems: {
349
+ type: "integer",
350
+ minimum: 0,
351
+ description: "Minimum number of items"
352
+ },
353
+ maxItems: {
354
+ type: "integer",
355
+ minimum: 0,
356
+ description: "Maximum number of items"
357
+ }
358
+ })
359
+ ]
360
+ };
361
+ var methodArgumentsEditorJsonSchema = {
362
+ $schema: "https://json-schema.org/draft/2020-12/schema",
363
+ type: "array",
364
+ description: "Positional method parameters passed to the assistant tool",
365
+ items: methodArgumentItemJsonSchema
366
+ };
367
+ function sanitizeMethodArgumentForType(arg, nextType) {
368
+ const base = {
369
+ type: nextType,
370
+ ...arg.description !== undefined ? { description: arg.description } : {},
371
+ ...arg.enum !== undefined ? { enum: arg.enum } : {},
372
+ ...arg.examples !== undefined ? { examples: arg.examples } : {}
373
+ };
374
+ switch (nextType) {
375
+ case "string":
376
+ return {
377
+ ...base,
378
+ ...arg.minLength !== undefined ? { minLength: arg.minLength } : {},
379
+ ...arg.maxLength !== undefined ? { maxLength: arg.maxLength } : {},
380
+ ...typeof arg.pattern === "string" ? { pattern: arg.pattern } : {}
381
+ };
382
+ case "integer":
383
+ case "number":
384
+ return {
385
+ ...base,
386
+ ...arg.minimum !== undefined ? { minimum: arg.minimum } : {},
387
+ ...arg.maximum !== undefined ? { maximum: arg.maximum } : {}
388
+ };
389
+ case "boolean":
390
+ return base;
391
+ case "object":
392
+ return {
393
+ ...base,
394
+ ...arg.properties !== undefined ? { properties: arg.properties } : {},
395
+ ...arg.required !== undefined ? { required: arg.required } : {},
396
+ ...arg.additionalProperties !== undefined ? { additionalProperties: arg.additionalProperties } : {}
397
+ };
398
+ case "array":
399
+ return {
400
+ ...base,
401
+ ...arg.items !== undefined ? { items: arg.items } : {},
402
+ ...arg.minItems !== undefined ? { minItems: arg.minItems } : {},
403
+ ...arg.maxItems !== undefined ? { maxItems: arg.maxItems } : {}
404
+ };
405
+ }
406
+ }
407
+ function isMethodArgumentSchema(value) {
408
+ if (!value || typeof value !== "object" || Array.isArray(value))
409
+ return false;
410
+ const type = value.type;
411
+ return type === "string" || type === "integer" || type === "number" || type === "boolean" || type === "object" || type === "array";
412
+ }
413
+ function parseMethodArguments(value) {
414
+ if (!Array.isArray(value))
415
+ return;
416
+ const parsed = value.filter(isMethodArgumentSchema);
417
+ return parsed.length > 0 ? parsed : undefined;
418
+ }
419
+ function migrateParamsSchemaToArguments(paramsSchema) {
420
+ if (!paramsSchema)
421
+ return;
422
+ if (paramsSchema.type === "array" && Array.isArray(paramsSchema.prefixItems)) {
423
+ return parseMethodArguments(paramsSchema.prefixItems);
424
+ }
425
+ return;
426
+ }
427
+ function argumentsToParamsSchema(args) {
428
+ if (args.length === 0) {
429
+ return { type: "array", items: {} };
430
+ }
431
+ return {
432
+ type: "array",
433
+ prefixItems: args,
434
+ minItems: args.length,
435
+ maxItems: args.length
436
+ };
437
+ }
438
+ function buildParamsPropertySchema(args) {
439
+ if (!args?.length) {
440
+ return {
441
+ type: "array",
442
+ description: "Function parameters as a JSON array (positional)",
443
+ items: {}
444
+ };
445
+ }
446
+ return {
447
+ description: "Function parameters as a JSON array (positional)",
448
+ ...argumentsToParamsSchema(args)
449
+ };
450
+ }
451
+ // src/tools/method-tools.ts
452
+ function normalizeApplyTo(applyTo) {
453
+ switch (applyTo) {
454
+ case "entity":
455
+ return "entity";
456
+ case "entitySelection":
457
+ return "entitySelection";
458
+ case "dataClass":
459
+ return "dataclass";
460
+ default:
461
+ return "dataclass";
462
+ }
463
+ }
464
+ function buildMethodToolName(input) {
465
+ switch (input.scope) {
466
+ case "entity":
467
+ return `@dataclass/${input.dataClass}/Entity/${input.methodName}`;
468
+ case "entitySelection":
469
+ return `@dataclass/${input.dataClass}/EntitySet/${input.methodName}`;
470
+ case "singleton":
471
+ return `@datastore/singletons/${input.singletonName}/${input.methodName}`;
472
+ case "catalog":
473
+ return `@datastore/methods/${input.methodName}`;
474
+ default:
475
+ return `@dataclass/${input.dataClass}/${input.methodName}`;
476
+ }
477
+ }
478
+ function buildInputSchema(candidate) {
479
+ const properties = {
480
+ params: buildParamsPropertySchema(candidate.metadata?.arguments)
481
+ };
482
+ const required = [];
483
+ if (candidate.scope === "entity") {
484
+ properties.key = {
485
+ type: "string",
486
+ description: "Entity primary key"
487
+ };
488
+ required.push("key");
489
+ }
490
+ if (candidate.scope === "entitySelection") {
491
+ properties.filter = {
492
+ type: "string",
493
+ description: "4D filter expression for the entity selection"
494
+ };
495
+ properties.entitySetId = {
496
+ type: "string",
497
+ description: "Existing entity set ID (alternative to filter)"
498
+ };
499
+ properties.orderby = {
500
+ type: "string",
501
+ description: "Order by expression for the entity selection"
502
+ };
503
+ }
504
+ if (candidate.metadata?.arguments?.length) {
505
+ required.push("params");
506
+ }
507
+ return {
508
+ type: "object",
509
+ properties,
510
+ required: required.length > 0 ? required : undefined,
511
+ additionalProperties: false
512
+ };
513
+ }
514
+ function buildDescription(candidate) {
515
+ if (candidate.metadata?.description?.trim()) {
516
+ return candidate.metadata.description.trim();
517
+ }
518
+ const signature = candidate.paramsText?.trim();
519
+ const target = candidate.scope === "singleton" ? `${candidate.singletonName}.${candidate.methodName}` : candidate.scope === "catalog" ? candidate.methodName : `${candidate.dataClass}.${candidate.methodName}`;
520
+ const httpMethod = candidate.allowedOnHTTPGET ? "GET or POST" : "POST";
521
+ if (signature) {
522
+ return `Call ${target} (${httpMethod}). Signature: ${signature}`;
523
+ }
524
+ return `Call ${target} (${httpMethod})`;
525
+ }
526
+ function defaultIsMethodExposed(method) {
527
+ if (method.exposed === true)
528
+ return true;
529
+ if (method.exposed === false)
530
+ return false;
531
+ const scope = typeof method.scope === "string" ? method.scope.trim() : "";
532
+ if (scope === "publicOnServer")
533
+ return false;
534
+ if (scope === "public")
535
+ return true;
536
+ return false;
537
+ }
538
+ function collectCandidates(options) {
539
+ const { catalog, metadata } = options;
540
+ const isExposed = options.isMethodExposed ?? defaultIsMethodExposed;
541
+ const candidates = [];
542
+ for (const dataClass of catalog.dataClasses ?? []) {
543
+ for (const method of dataClass.methods ?? []) {
544
+ if (!method.name || !isExposed(method))
545
+ continue;
546
+ const scope = normalizeApplyTo(method.applyTo);
547
+ candidates.push({
548
+ toolName: buildMethodToolName({
549
+ scope,
550
+ dataClass: dataClass.name,
551
+ methodName: method.name
552
+ }),
553
+ scope,
554
+ dataClass: dataClass.name,
555
+ methodName: method.name,
556
+ allowedOnHTTPGET: method.allowedOnHTTPGET,
557
+ paramsText: method.paramsText,
558
+ metadata: metadata?.dataClasses?.[dataClass.name]?.methods?.[method.name]
559
+ });
560
+ }
561
+ }
562
+ for (const singleton of catalog.singletons ?? []) {
563
+ for (const method of singleton.methods ?? []) {
564
+ if (!method.name || !isExposed(method))
565
+ continue;
566
+ candidates.push({
567
+ toolName: buildMethodToolName({
568
+ scope: "singleton",
569
+ singletonName: singleton.name,
570
+ methodName: method.name
571
+ }),
572
+ scope: "singleton",
573
+ singletonName: singleton.name,
574
+ methodName: method.name,
575
+ allowedOnHTTPGET: method.allowedOnHTTPGET,
576
+ paramsText: method.paramsText,
577
+ metadata: metadata?.singletons?.[singleton.name]?.methods?.[method.name]
578
+ });
579
+ }
580
+ }
581
+ for (const method of catalog.methods ?? []) {
582
+ if (!method.name || !isExposed(method))
583
+ continue;
584
+ candidates.push({
585
+ toolName: buildMethodToolName({
586
+ scope: "catalog",
587
+ methodName: method.name
588
+ }),
589
+ scope: "catalog",
590
+ methodName: method.name,
591
+ allowedOnHTTPGET: method.allowedOnHTTPGET,
592
+ paramsText: method.paramsText,
593
+ metadata: metadata?.catalogMethods?.[method.name]
594
+ });
595
+ }
596
+ return candidates;
597
+ }
598
+ function buildMethodToolHandlers(options) {
599
+ const candidates = collectCandidates(options);
600
+ const usedNames = new Set;
601
+ return candidates.map((candidate) => {
602
+ let toolName = candidate.toolName;
603
+ if (usedNames.has(toolName)) {
604
+ toolName = `${candidate.scope}_${toolName}`;
605
+ }
606
+ usedNames.add(toolName);
607
+ return {
608
+ definition: {
609
+ name: toolName,
610
+ description: buildDescription(candidate),
611
+ inputSchema: buildInputSchema(candidate)
612
+ },
613
+ invoke: async (args) => {
614
+ const input = args;
615
+ if (candidate.scope === "entity" && input.key === undefined) {
616
+ return toolResultErr("key is required for entity methods");
617
+ }
618
+ if (candidate.scope === "entitySelection" && !input.filter && !input.entitySetId) {
619
+ return toolResultErr("filter or entitySetId is required for entity selection methods");
620
+ }
621
+ try {
622
+ const result = await options.invoke({
623
+ scope: candidate.scope,
624
+ dataClass: candidate.dataClass,
625
+ singletonName: candidate.singletonName,
626
+ methodName: candidate.methodName,
627
+ params: input.params ?? [],
628
+ key: input.key,
629
+ filter: input.filter,
630
+ orderby: input.orderby,
631
+ entitySetId: input.entitySetId,
632
+ allowedOnHTTPGET: candidate.allowedOnHTTPGET
633
+ });
634
+ return toolResultOk(result);
635
+ } catch (error) {
636
+ return toolResultErr(error instanceof Error ? error.message : String(error));
637
+ }
638
+ }
639
+ };
640
+ });
641
+ }
243
642
  export {
643
+ sanitizeMethodArgumentForType,
244
644
  resolveAssistantToolHooks,
245
645
  registerDatastoreTools,
646
+ parseMethodArguments,
647
+ migrateParamsSchemaToArguments,
648
+ methodArgumentsEditorJsonSchema,
649
+ methodArgumentItemJsonSchema,
650
+ isMethodArgumentSchema,
246
651
  createAssistantToolRegistry,
247
- connectExternalTools
652
+ connectExternalTools,
653
+ buildParamsPropertySchema,
654
+ buildMethodToolName,
655
+ buildMethodToolHandlers,
656
+ argumentsToParamsSchema,
657
+ METHOD_ARGUMENT_TYPES
248
658
  };
@@ -0,0 +1,35 @@
1
+ export type MethodArgumentType = "string" | "integer" | "number" | "boolean" | "object" | "array";
2
+ export declare const METHOD_ARGUMENT_TYPES: readonly MethodArgumentType[];
3
+ /** JSON Schema for a single positional method parameter (type-specific fields). */
4
+ export declare const methodArgumentItemJsonSchema: Record<string, unknown>;
5
+ /** JSON Schema for editing method `arguments` arrays in metadata. */
6
+ export declare const methodArgumentsEditorJsonSchema: Record<string, unknown>;
7
+ export interface MethodArgumentSchema {
8
+ type: MethodArgumentType;
9
+ description?: string;
10
+ minimum?: number;
11
+ maximum?: number;
12
+ minLength?: number;
13
+ maxLength?: number;
14
+ pattern?: string;
15
+ enum?: unknown[];
16
+ examples?: unknown[];
17
+ properties?: Record<string, unknown>;
18
+ required?: string[];
19
+ additionalProperties?: boolean | Record<string, unknown>;
20
+ items?: Record<string, unknown>;
21
+ minItems?: number;
22
+ maxItems?: number;
23
+ [key: string]: unknown;
24
+ }
25
+ /** Keep only fields valid for the target JSON Schema type. */
26
+ export declare function sanitizeMethodArgumentForType(arg: MethodArgumentSchema, nextType: MethodArgumentType): MethodArgumentSchema;
27
+ export declare function isMethodArgumentSchema(value: unknown): value is MethodArgumentSchema;
28
+ export declare function parseMethodArguments(value: unknown): MethodArgumentSchema[] | undefined;
29
+ /** Migrate legacy paramsSchema with prefixItems to arguments[]. */
30
+ export declare function migrateParamsSchemaToArguments(paramsSchema: Record<string, unknown> | undefined): MethodArgumentSchema[] | undefined;
31
+ /** Positional arguments → JSON Schema array with prefixItems (4D REST params body). */
32
+ export declare function argumentsToParamsSchema(args: MethodArgumentSchema[]): Record<string, unknown>;
33
+ /** Build the `params` property schema for a method tool inputSchema. */
34
+ export declare function buildParamsPropertySchema(args: MethodArgumentSchema[] | undefined): Record<string, unknown>;
35
+ //# sourceMappingURL=method-arguments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-arguments.d.ts","sourceRoot":"","sources":["../../src/tools/method-arguments.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,CAAC;AAEZ,eAAO,MAAM,qBAAqB,EAAE,SAAS,kBAAkB,EAOrD,CAAC;AA2CX,mFAAmF;AACnF,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAwEhE,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,+BAA+B,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAKnE,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,kBAAkB,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,8DAA8D;AAC9D,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,oBAAoB,EACzB,QAAQ,EAAE,kBAAkB,GAC3B,oBAAoB,CA0CtB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAWpF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,EAAE,GAAG,SAAS,CAIvF;AAED,mEAAmE;AACnE,wBAAgB,8BAA8B,CAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAChD,oBAAoB,EAAE,GAAG,SAAS,CAMpC;AAED,uFAAuF;AACvF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,oBAAoB,EAAE,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAED,wEAAwE;AACxE,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,oBAAoB,EAAE,GAAG,SAAS,GACvC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB"}
@@ -0,0 +1,62 @@
1
+ import type { AssistantToolHandler } from "../core/tool-registry.js";
2
+ import { type MethodArgumentSchema } from "./method-arguments.js";
3
+ export type MethodToolScope = "dataclass" | "entity" | "entitySelection" | "singleton" | "catalog";
4
+ export interface MethodToolCatalogMethod {
5
+ name: string;
6
+ applyTo?: string;
7
+ exposed?: boolean;
8
+ allowedOnHTTPGET?: boolean;
9
+ scope?: string;
10
+ paramsText?: string;
11
+ }
12
+ export interface MethodToolCatalog {
13
+ dataClasses?: Array<{
14
+ name: string;
15
+ methods?: MethodToolCatalogMethod[];
16
+ }>;
17
+ singletons?: Array<{
18
+ name: string;
19
+ methods?: MethodToolCatalogMethod[];
20
+ }>;
21
+ methods?: MethodToolCatalogMethod[];
22
+ }
23
+ export interface MethodToolMetadata {
24
+ description?: string;
25
+ arguments?: MethodArgumentSchema[];
26
+ }
27
+ export interface MethodToolMetadataSchema {
28
+ dataClasses?: Record<string, {
29
+ methods?: Record<string, MethodToolMetadata>;
30
+ }>;
31
+ singletons?: Record<string, {
32
+ methods?: Record<string, MethodToolMetadata>;
33
+ }>;
34
+ catalogMethods?: Record<string, MethodToolMetadata>;
35
+ }
36
+ export interface MethodToolInvokeInput {
37
+ scope: MethodToolScope;
38
+ dataClass?: string;
39
+ singletonName?: string;
40
+ methodName: string;
41
+ params?: unknown[];
42
+ key?: string | number;
43
+ filter?: string;
44
+ orderby?: string;
45
+ entitySetId?: string;
46
+ allowedOnHTTPGET?: boolean;
47
+ }
48
+ export type MethodToolInvokeFn = (input: MethodToolInvokeInput) => Promise<unknown>;
49
+ export interface BuildMethodToolHandlersOptions {
50
+ catalog: MethodToolCatalog;
51
+ metadata: MethodToolMetadataSchema | null | undefined;
52
+ invoke: MethodToolInvokeFn;
53
+ isMethodExposed?: (method: MethodToolCatalogMethod) => boolean;
54
+ }
55
+ export declare function buildMethodToolName(input: {
56
+ scope: MethodToolScope;
57
+ dataClass?: string;
58
+ singletonName?: string;
59
+ methodName: string;
60
+ }): string;
61
+ export declare function buildMethodToolHandlers(options: BuildMethodToolHandlersOptions): AssistantToolHandler[];
62
+ //# sourceMappingURL=method-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-tools.d.ts","sourceRoot":"","sources":["../../src/tools/method-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,QAAQ,GACR,iBAAiB,GACjB,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,uBAAuB,EAAE,CAAC;KACrC,CAAC,CAAC;IACH,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,uBAAuB,EAAE,CAAC;KACrC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,uBAAuB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,CAAC,EAAE,MAAM,CAClB,MAAM,EACN;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;KAAE,CACjD,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CACjB,MAAM,EACN;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;KAAE,CACjD,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,kBAAkB,GAAG,CAC/B,KAAK,EAAE,qBAAqB,KACzB,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,EAAE,wBAAwB,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,MAAM,EAAE,kBAAkB,CAAC;IAC3B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC;CAChE;AA0BD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAaT;AAuID,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,8BAA8B,GACtC,oBAAoB,EAAE,CA8DxB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4djs/assistant",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "type": "module",
5
5
  "types": "./dist/react/index.d.ts",
6
6
  "files": [