@dxos/assistant 0.8.4-main.fd6878d → 0.8.4-staging.60fe92afc8

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 (183) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +2 -1
  3. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  4. package/dist/lib/neutral/extraction/index.mjs +208 -0
  5. package/dist/lib/neutral/extraction/index.mjs.map +7 -0
  6. package/dist/lib/neutral/index.mjs +1886 -0
  7. package/dist/lib/neutral/index.mjs.map +7 -0
  8. package/dist/lib/neutral/meta.json +1 -0
  9. package/dist/types/src/extraction/extraction-ner-function/index.d.ts +0 -1
  10. package/dist/types/src/extraction/extraction-ner-function/index.d.ts.map +1 -1
  11. package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -1
  12. package/dist/types/src/extraction/extraction.d.ts +1650 -281
  13. package/dist/types/src/extraction/extraction.d.ts.map +1 -1
  14. package/dist/types/src/extraction/index.d.ts +0 -1
  15. package/dist/types/src/extraction/index.d.ts.map +1 -1
  16. package/dist/types/src/extraction/quotes.d.ts +3 -3
  17. package/dist/types/src/extraction/quotes.d.ts.map +1 -1
  18. package/dist/types/src/functions/services.d.ts +16 -5
  19. package/dist/types/src/functions/services.d.ts.map +1 -1
  20. package/dist/types/src/index.d.ts +2 -3
  21. package/dist/types/src/index.d.ts.map +1 -1
  22. package/dist/types/src/request/AiRequest.d.ts +308 -0
  23. package/dist/types/src/request/AiRequest.d.ts.map +1 -0
  24. package/dist/types/src/{session → request}/artifact-diff.d.ts +5 -5
  25. package/dist/types/src/request/artifact-diff.d.ts.map +1 -0
  26. package/dist/types/src/request/format.d.ts +15 -0
  27. package/dist/types/src/request/format.d.ts.map +1 -0
  28. package/dist/types/src/request/index.d.ts +4 -0
  29. package/dist/types/src/request/index.d.ts.map +1 -0
  30. package/dist/types/src/request/observer.d.ts +23 -0
  31. package/dist/types/src/request/observer.d.ts.map +1 -0
  32. package/dist/types/src/{session → request}/version-pin.d.ts +6 -6
  33. package/dist/types/src/request/version-pin.d.ts.map +1 -0
  34. package/dist/types/src/session/AiContext.d.ts +178 -0
  35. package/dist/types/src/session/AiContext.d.ts.map +1 -0
  36. package/dist/types/src/session/AiContext.test.d.ts +2 -0
  37. package/dist/types/src/session/AiContext.test.d.ts.map +1 -0
  38. package/dist/types/src/session/AiSession.d.ts +79 -0
  39. package/dist/types/src/session/AiSession.d.ts.map +1 -0
  40. package/dist/types/src/session/AiSession.test.d.ts +2 -0
  41. package/dist/types/src/session/AiSession.test.d.ts.map +1 -0
  42. package/dist/types/src/session/SessionLink.d.ts +17 -0
  43. package/dist/types/src/session/SessionLink.d.ts.map +1 -0
  44. package/dist/types/src/session/SessionLoader.d.ts +15 -0
  45. package/dist/types/src/session/SessionLoader.d.ts.map +1 -0
  46. package/dist/types/src/session/SessionLoader.test.d.ts +2 -0
  47. package/dist/types/src/session/SessionLoader.test.d.ts.map +1 -0
  48. package/dist/types/src/session/index.d.ts +5 -3
  49. package/dist/types/src/session/index.d.ts.map +1 -1
  50. package/dist/types/src/session/toolkit.d.ts +16 -0
  51. package/dist/types/src/session/toolkit.d.ts.map +1 -0
  52. package/dist/types/src/templates/system.d.ts +19 -14
  53. package/dist/types/src/templates/system.d.ts.map +1 -1
  54. package/dist/types/src/util/artifact.d.ts +18 -0
  55. package/dist/types/src/util/artifact.d.ts.map +1 -0
  56. package/dist/types/src/util/diff.d.ts +17 -0
  57. package/dist/types/src/util/diff.d.ts.map +1 -0
  58. package/dist/types/src/util/diff.test.d.ts +2 -0
  59. package/dist/types/src/util/diff.test.d.ts.map +1 -0
  60. package/dist/types/src/util/error-handling.d.ts +4 -0
  61. package/dist/types/src/util/error-handling.d.ts.map +1 -0
  62. package/dist/types/src/util/errors.d.ts +67 -0
  63. package/dist/types/src/util/errors.d.ts.map +1 -0
  64. package/dist/types/src/util/execution-graph.d.ts +85 -0
  65. package/dist/types/src/util/execution-graph.d.ts.map +1 -0
  66. package/dist/types/src/util/execution-graph.test.d.ts +2 -0
  67. package/dist/types/src/util/execution-graph.test.d.ts.map +1 -0
  68. package/dist/types/src/util/index.d.ts +7 -0
  69. package/dist/types/src/util/index.d.ts.map +1 -0
  70. package/dist/types/src/util/tracing.d.ts +296 -0
  71. package/dist/types/src/util/tracing.d.ts.map +1 -0
  72. package/dist/types/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +37 -47
  74. package/src/extraction/extraction-ner-function/index.ts +0 -1
  75. package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +12 -6
  76. package/src/extraction/extraction-ner-function/named-entity-recognition.ts +2 -0
  77. package/src/extraction/extraction.ts +49 -19
  78. package/src/extraction/index.ts +0 -1
  79. package/src/extraction/quotes.test.ts +2 -2
  80. package/src/extraction/quotes.ts +7 -9
  81. package/src/functions/services.ts +180 -66
  82. package/src/index.ts +2 -3
  83. package/src/request/AiRequest.ts +387 -0
  84. package/src/{session → request}/artifact-diff.ts +10 -6
  85. package/src/{session → request}/format.ts +45 -37
  86. package/src/request/index.ts +8 -0
  87. package/src/request/observer.ts +62 -0
  88. package/src/{session → request}/version-pin.ts +8 -8
  89. package/src/session/AiContext.test.ts +49 -0
  90. package/src/session/AiContext.ts +420 -0
  91. package/src/session/AiSession.test.ts +111 -0
  92. package/src/session/AiSession.ts +328 -0
  93. package/src/session/SessionLink.ts +23 -0
  94. package/src/session/SessionLoader.test.ts +115 -0
  95. package/src/session/SessionLoader.ts +55 -0
  96. package/src/session/index.ts +6 -3
  97. package/src/session/toolkit.ts +47 -0
  98. package/src/templates/{format.tpl → instructions/format.tpl} +6 -4
  99. package/src/templates/instructions/system.tpl +96 -0
  100. package/src/templates/system.ts +26 -16
  101. package/src/util/artifact.ts +96 -0
  102. package/src/util/diff.test.ts +74 -0
  103. package/src/util/diff.ts +93 -0
  104. package/src/util/error-handling.ts +42 -0
  105. package/src/util/errors.ts +15 -0
  106. package/src/util/execution-graph.test.ts +740 -0
  107. package/src/util/execution-graph.ts +520 -0
  108. package/src/util/index.ts +10 -0
  109. package/src/util/tracing.ts +60 -0
  110. package/dist/lib/browser/chunk-6WRGDEMH.mjs +0 -89
  111. package/dist/lib/browser/chunk-6WRGDEMH.mjs.map +0 -7
  112. package/dist/lib/browser/chunk-NZGGCEF3.mjs +0 -341
  113. package/dist/lib/browser/chunk-NZGGCEF3.mjs.map +0 -7
  114. package/dist/lib/browser/extraction/index.mjs +0 -269
  115. package/dist/lib/browser/extraction/index.mjs.map +0 -7
  116. package/dist/lib/browser/index.mjs +0 -354
  117. package/dist/lib/browser/index.mjs.map +0 -7
  118. package/dist/lib/browser/meta.json +0 -1
  119. package/dist/lib/browser/named-entity-recognition-O46UTCLR.mjs +0 -13
  120. package/dist/lib/node-esm/chunk-3UU5V4FS.mjs +0 -91
  121. package/dist/lib/node-esm/chunk-3UU5V4FS.mjs.map +0 -7
  122. package/dist/lib/node-esm/chunk-XOOPGSGW.mjs +0 -343
  123. package/dist/lib/node-esm/chunk-XOOPGSGW.mjs.map +0 -7
  124. package/dist/lib/node-esm/extraction/index.mjs +0 -270
  125. package/dist/lib/node-esm/extraction/index.mjs.map +0 -7
  126. package/dist/lib/node-esm/index.mjs +0 -355
  127. package/dist/lib/node-esm/index.mjs.map +0 -7
  128. package/dist/lib/node-esm/meta.json +0 -1
  129. package/dist/lib/node-esm/named-entity-recognition-W4VMRCH6.mjs +0 -14
  130. package/dist/lib/node-esm/named-entity-recognition-W4VMRCH6.mjs.map +0 -7
  131. package/dist/types/src/conversation/context.d.ts +0 -90
  132. package/dist/types/src/conversation/context.d.ts.map +0 -1
  133. package/dist/types/src/conversation/conversation.d.ts +0 -50
  134. package/dist/types/src/conversation/conversation.d.ts.map +0 -1
  135. package/dist/types/src/conversation/index.d.ts +0 -3
  136. package/dist/types/src/conversation/index.d.ts.map +0 -1
  137. package/dist/types/src/errors.d.ts +0 -39
  138. package/dist/types/src/errors.d.ts.map +0 -1
  139. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts +0 -4
  140. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +0 -1
  141. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts +0 -2
  142. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts.map +0 -1
  143. package/dist/types/src/extraction/extraction-llm-function/index.d.ts +0 -2
  144. package/dist/types/src/extraction/extraction-llm-function/index.d.ts.map +0 -1
  145. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +0 -306
  146. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +0 -1
  147. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts +0 -2
  148. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts.map +0 -1
  149. package/dist/types/src/session/artifact-diff.d.ts.map +0 -1
  150. package/dist/types/src/session/format.d.ts +0 -168
  151. package/dist/types/src/session/format.d.ts.map +0 -1
  152. package/dist/types/src/session/format.test.d.ts +0 -2
  153. package/dist/types/src/session/format.test.d.ts.map +0 -1
  154. package/dist/types/src/session/session.d.ts +0 -167
  155. package/dist/types/src/session/session.d.ts.map +0 -1
  156. package/dist/types/src/session/session.test.d.ts +0 -2
  157. package/dist/types/src/session/session.test.d.ts.map +0 -1
  158. package/dist/types/src/session/version-pin.d.ts.map +0 -1
  159. package/dist/types/src/session/version-pin.test.d.ts +0 -2
  160. package/dist/types/src/session/version-pin.test.d.ts.map +0 -1
  161. package/dist/types/src/summarization/summarization.test.d.ts +0 -2
  162. package/dist/types/src/summarization/summarization.test.d.ts.map +0 -1
  163. package/dist/types/src/types.d.ts +0 -16
  164. package/dist/types/src/types.d.ts.map +0 -1
  165. package/src/conversation/context.ts +0 -133
  166. package/src/conversation/conversation.ts +0 -125
  167. package/src/conversation/index.ts +0 -6
  168. package/src/errors.ts +0 -10
  169. package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +0 -84
  170. package/src/extraction/extraction-llm-function/extraction-llm-function.ts +0 -71
  171. package/src/extraction/extraction-llm-function/index.ts +0 -5
  172. package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +0 -116
  173. package/src/extraction/extraction-ner-function/extraction-ner-function.ts +0 -57
  174. package/src/session/__snapshots__/session.test.ts.snap +0 -32
  175. package/src/session/format.test.ts +0 -60
  176. package/src/session/session.test.ts +0 -305
  177. package/src/session/session.ts +0 -279
  178. package/src/session/version-pin.test.ts +0 -7
  179. package/src/summarization/summarization.test.ts +0 -197
  180. package/src/templates/system.tpl +0 -47
  181. package/src/types.ts +0 -52
  182. /package/dist/lib/{browser/named-entity-recognition-O46UTCLR.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  183. /package/src/extraction/extraction-llm-function/{instructions.tpl → transcription-instructions.tpl} +0 -0
@@ -2,94 +2,163 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { AiTool, type AiToolkit } from '@effect/ai';
6
- import { Context, Effect, Layer, Match, Predicate, Record, Schema } from 'effect';
5
+ import * as Tool from '@effect/ai/Tool';
6
+ import type * as Toolkit from '@effect/ai/Toolkit';
7
+ import * as Context from 'effect/Context';
8
+ import * as Effect from 'effect/Effect';
9
+ import * as Layer from 'effect/Layer';
10
+ import * as Option from 'effect/Option';
11
+ import * as Record from 'effect/Record';
12
+ import * as Schema from 'effect/Schema';
13
+ import * as SchemaAST from 'effect/SchemaAST';
7
14
 
8
15
  import { AiToolNotFoundError, ToolExecutionService, ToolResolverService } from '@dxos/ai';
9
- import { type FunctionDefinition, LocalFunctionExecutionService } from '@dxos/functions';
16
+ import { OpaqueToolkit } from '@dxos/ai';
17
+ import { Operation } from '@dxos/compute';
18
+ import { todo } from '@dxos/debug';
19
+ import { DXN, Filter, Ref, Registry } from '@dxos/echo';
10
20
  import { invariant } from '@dxos/invariant';
11
21
 
12
- export const makeToolResolverFromFunctions = (
13
- functions: FunctionDefinition<any, any>[],
14
- toolkit: AiToolkit.Any,
15
- ): Layer.Layer<ToolResolverService> => {
16
- return Layer.succeed(ToolResolverService, {
17
- resolve: Effect.fn('resolveTool')(function* (id) {
18
- const tool = toolkit.tools[id];
19
- if (tool) {
20
- return tool;
21
- }
22
-
23
- const fn = functions.find((f) => f.name === id);
24
- if (!fn) {
25
- return yield* Effect.fail(new AiToolNotFoundError(id));
26
- }
27
-
28
- return projectFunctionToTool(fn);
22
+ import { RefFromLLM } from '../util';
23
+
24
+ export const makeToolResolverFromOperations = <R = never>({
25
+ toolkit: extraToolkit = OpaqueToolkit.empty,
26
+ }: { toolkit?: OpaqueToolkit.OpaqueToolkit<never, never, R> } = {}): Layer.Layer<
27
+ ToolResolverService,
28
+ never,
29
+ OpaqueToolkit.OpaqueToolkitProvider | Registry.Service | R
30
+ > => {
31
+ return Layer.effect(
32
+ ToolResolverService,
33
+ Effect.gen(function* () {
34
+ const toolkitProvider = yield* OpaqueToolkit.OpaqueToolkitProvider;
35
+ const registry = yield* Registry.Service;
36
+ return {
37
+ resolve: (id): Effect.Effect<Tool.Any, AiToolNotFoundError> =>
38
+ Effect.gen(function* () {
39
+ const toolkit = OpaqueToolkit.merge(extraToolkit, toolkitProvider.getToolkit());
40
+
41
+ const tool = toolkit.toolkit.tools[id];
42
+ if (tool) {
43
+ return tool;
44
+ }
45
+
46
+ // Normalize to a full DXN key (tool IDs are plain NSIDs, stored keys are full DXNs).
47
+ const key = DXN.isDXN(id) ? id : `dxn:${id}`;
48
+ const results = yield* Effect.promise(() =>
49
+ registry.query(Filter.and(Filter.type(Operation.PersistentOperation), Filter.key(key))).run(),
50
+ );
51
+ if (results.length > 0) {
52
+ return projectFunctionToTool(Operation.deserialize(results[0]));
53
+ }
54
+ return yield* Effect.fail(new AiToolNotFoundError(id));
55
+ }),
56
+ } satisfies Context.Tag.Service<ToolResolverService>;
29
57
  }),
30
- });
58
+ );
31
59
  };
32
60
 
33
- export const makeToolExecutionServiceFromFunctions = (
34
- functions: FunctionDefinition<any, any>[],
35
- toolkit: AiToolkit.AiToolkit<AiTool.Any>,
36
- handlersLayer: Layer.Layer<AiTool.ToHandler<AiTool.AiTool<any>>, never, never>,
37
- ): Layer.Layer<ToolExecutionService, never, LocalFunctionExecutionService> => {
38
- return Layer.effect(
61
+ export const makeToolExecutionService = <E, R>(opts: {
62
+ invoke: (tool: Tool.Any, input: unknown) => Effect.Effect<unknown>;
63
+ }): Layer.Layer<ToolExecutionService, never, OpaqueToolkit.OpaqueToolkitProvider> =>
64
+ Layer.effect(
39
65
  ToolExecutionService,
40
66
  Effect.gen(function* () {
41
- const toolkitHandler = yield* toolkit.pipe(Effect.provide(handlersLayer));
67
+ const toolkitProvider = yield* OpaqueToolkit.OpaqueToolkitProvider;
68
+ const toolkit = toolkitProvider.getToolkit();
69
+
70
+ const toolkitHandler = yield* toolkit.toolkit.pipe(Effect.provide(toolkit.layer));
71
+ invariant(isHandlerLike(toolkitHandler));
42
72
 
43
- const localFunctionExecutionService = yield* LocalFunctionExecutionService;
44
73
  return {
45
74
  handlersFor: (toolkit) => {
46
- const makeHandler = (tool: AiTool.Any): ((params: unknown) => Effect.Effect<unknown, any, any>) => {
47
- return Effect.fn('toolFunctionHandler')(function* (input: any) {
48
- if (toolkitHandler.tools.find((t: AiTool.Any) => t.name === tool.name)) {
49
- // TODO(wittjosiah): Everything is `never` here.
50
- return yield* (toolkitHandler.handle as any)(tool.name, input);
51
- }
75
+ const makeHandler = (tool: Tool.Any): ((params: unknown) => Effect.Effect<unknown, any, any>) => {
76
+ return Effect.fn(`toolFunctionHandler ${tool.name}`)(function* (input: any) {
77
+ if (toolkitHandler.tools[tool.name]) {
78
+ if (Tool.isProviderDefined(tool)) {
79
+ throw new Error('Attempted to call a provider-defined tool');
80
+ }
52
81
 
53
- const { functionName } = Context.get(FunctionToolAnnotation)(tool.annotations as any);
54
- const fnDef = functions.find((f) => f.name === functionName);
55
- if (!fnDef) {
56
- return yield* Effect.fail(new AiToolNotFoundError(tool.name));
82
+ // TODO(wittjosiah): Everything is `never` here.
83
+ const { result } = yield* (toolkitHandler.handle as any)(tool.name, input);
84
+ return result;
57
85
  }
58
86
 
59
- return yield* localFunctionExecutionService
60
- .invokeFunction(fnDef, input)
61
- .pipe(Effect.catchAllDefect((defect) => Effect.fail(defect)));
87
+ return yield* opts.invoke(tool, input).pipe(Effect.catchAllDefect((defect) => Effect.fail(defect)));
62
88
  });
63
89
  };
64
90
 
65
- return toolkit.of(Record.map(toolkit.tools, (tool, _name) => makeHandler(tool)) as any) as any;
91
+ return toolkit.of(
92
+ Record.map(toolkit.tools, (tool, _name) => (Tool.isUserDefined(tool) ? makeHandler(tool) : null)) as any,
93
+ ) as any;
66
94
  },
67
95
  };
68
96
  }),
69
97
  );
98
+
99
+ export const makeToolExecutionServiceFromOperationInvoker = (): Layer.Layer<
100
+ ToolExecutionService,
101
+ never,
102
+ Operation.Service | OpaqueToolkit.OpaqueToolkitProvider
103
+ > => {
104
+ return Layer.unwrapEffect(
105
+ Effect.gen(function* () {
106
+ const operationInvoker = yield* Operation.Service;
107
+
108
+ return makeToolExecutionService({
109
+ invoke: (tool, input) =>
110
+ Effect.gen(function* () {
111
+ const operationDef = getOperationFromTool(tool).pipe(Option.getOrThrow);
112
+
113
+ return yield* operationInvoker.invoke(operationDef, input).pipe(Effect.orDie);
114
+ }),
115
+ });
116
+ }),
117
+ );
70
118
  };
71
119
 
72
- /**
73
- * Tools that are projected from functions have this annotation.
74
- */
75
- class FunctionToolAnnotation extends Context.Tag('@dxos/assisatnt/FunctionToolAnnotation')<
120
+ export const ToolExecutionServices = Layer.mergeAll(
121
+ makeToolResolverFromOperations(),
122
+ makeToolExecutionServiceFromOperationInvoker(),
123
+ );
124
+
125
+ class FunctionToolAnnotation extends Context.Tag('@dxos/assistant/FunctionToolAnnotation')<
76
126
  FunctionToolAnnotation,
77
- {
78
- functionName: string;
79
- }
127
+ { definition: Operation.Definition.Any }
80
128
  >() {}
81
129
 
82
- const toolCache = new WeakMap<FunctionDefinition<any, any>, AiTool.Any>();
83
- const projectFunctionToTool = (fn: FunctionDefinition<any, any>): AiTool.Any => {
130
+ export const getOperationFromTool = (tool: Tool.Any): Option.Option<Operation.Definition.Any> => {
131
+ return Context.getOption(FunctionToolAnnotation)(tool.annotations).pipe(Option.map(({ definition }) => definition));
132
+ };
133
+
134
+ const toolCache = new WeakMap<Operation.Definition.Any, Tool.Any>();
135
+
136
+ /**
137
+ * Empty parameters schema annotated with an explicit JSON schema so that
138
+ * @effect/ai versions that call JSONSchema.fromAST directly (≥0.35.0) still
139
+ * produce a valid `{type: "object"}` for the Anthropic API instead of the
140
+ * constEmptyStruct `{anyOf: [{type:"object"},{type:"array"}]}`.
141
+ */
142
+ const EMPTY_PARAMETERS_SCHEMA = Schema.Struct({}).annotations({
143
+ [SchemaAST.JSONSchemaAnnotationId]: { type: 'object', properties: {}, required: [], additionalProperties: false },
144
+ });
145
+
146
+ /**
147
+ * Projects an `Operation.Definition` into an `AiTool`.
148
+ */
149
+ const projectFunctionToTool = (fn: Operation.Definition.Any): Tool.Any => {
84
150
  if (toolCache.has(fn)) {
85
151
  return toolCache.get(fn)!;
86
152
  }
87
- const tool = AiTool.make(makeToolName(fn.name), {
88
- description: fn.description,
89
- parameters: createStructFieldsFromSchema(fn.inputSchema),
90
- // TODO(dmaretskyi): Include output schema.
91
- failure: Schema.Any, // TODO(dmaretskyi): Better type for the failure?
92
- }).annotate(FunctionToolAnnotation, { functionName: fn.name });
153
+
154
+ const fields = createStructFieldsFromSchema(fn.input);
155
+ const parametersSchema = Object.keys(fields).length === 0 ? EMPTY_PARAMETERS_SCHEMA : Schema.Struct(fields);
156
+ const tool = Tool.make(makeToolName(fn.meta.name ?? fn.meta.key), {
157
+ description: fn.meta.description,
158
+ failure: Schema.Any,
159
+ })
160
+ .setParameters(parametersSchema)
161
+ .annotate(FunctionToolAnnotation, { definition: fn });
93
162
  toolCache.set(fn, tool);
94
163
  return tool;
95
164
  };
@@ -98,17 +167,62 @@ const projectFunctionToTool = (fn: FunctionDefinition<any, any>): AiTool.Any =>
98
167
  * @returns Tool name produced from function name by escaping invalid characters.
99
168
  */
100
169
  const makeToolName = (name: string) => {
101
- const toolName = name.replace(/[^a-zA-Z0-9]/g, '_');
102
- invariant(toolName.match(/^[a-zA-Z_][a-zA-Z0-9-_]*$/));
170
+ const toolName = name.toLowerCase().replace(/[^a-zA-Z0-9]/g, '-');
171
+ invariant(toolName.match(/^[a-z_][a-z0-9-_]*$/));
103
172
  return toolName;
104
173
  };
105
174
 
106
175
  // TODO(dmaretskyi): Factor out.
107
176
  const createStructFieldsFromSchema = (schema: Schema.Schema<any, any>): Record<string, Schema.Schema<any, any>> => {
108
- return Match.value(schema.ast).pipe(
109
- Match.when(Predicate.isTagged('TypeLiteral'), (ast) => {
110
- return Object.fromEntries(ast.propertySignatures.map((prop) => [prop.name, Schema.make(prop.type)]));
111
- }),
112
- Match.orElseAbsurd,
113
- );
177
+ switch (schema.ast._tag) {
178
+ case 'TypeLiteral':
179
+ return Object.fromEntries(
180
+ schema.ast.propertySignatures.map((prop) => [prop.name, Schema.make(mapSchemaTypeForLLM(prop.type))]),
181
+ );
182
+ case 'VoidKeyword':
183
+ return {};
184
+ default:
185
+ return todo(`Unsupported schema AST: ${schema.ast._tag}`);
186
+ }
187
+ };
188
+
189
+ /**
190
+ * Picks an LLM-friendly schema type for the given schema AST.
191
+ * The picked schema type decodes to the original schema type.
192
+ */
193
+ const mapSchemaTypeForLLM = (ast: SchemaAST.AST): SchemaAST.AST => {
194
+ if (Ref.isRefType(ast)) {
195
+ const description = ast.annotations.description
196
+ ? ast.annotations.description + '\n' + RefFromLLM.ast.annotations.description
197
+ : (RefFromLLM.ast.annotations.description as string);
198
+ return RefFromLLM.annotations({ description }).ast;
199
+ } else if (SchemaAST.isTupleType(ast)) {
200
+ return new SchemaAST.TupleType(
201
+ ast.elements.map((t) => new SchemaAST.OptionalType(mapSchemaTypeForLLM(t.type), t.isOptional, t.annotations)),
202
+ ast.rest.map((t) => new SchemaAST.Type(mapSchemaTypeForLLM(t.type), t.annotations)),
203
+ ast.isReadonly,
204
+ ast.annotations,
205
+ );
206
+ } else if (SchemaAST.isTypeLiteral(ast)) {
207
+ return new SchemaAST.TypeLiteral(
208
+ ast.propertySignatures.map(
209
+ (p) =>
210
+ new SchemaAST.PropertySignature(
211
+ p.name,
212
+ mapSchemaTypeForLLM(p.type),
213
+ p.isOptional,
214
+ p.isReadonly,
215
+ p.annotations,
216
+ ),
217
+ ),
218
+ ast.indexSignatures,
219
+ ast.annotations,
220
+ );
221
+ }
222
+
223
+ return ast;
224
+ };
225
+
226
+ const isHandlerLike = (value: unknown): value is Toolkit.WithHandler<Record<string, Tool.Any>> => {
227
+ return typeof (value as any).tools === 'object' && typeof (value as any).handle === 'function';
114
228
  };
package/src/index.ts CHANGED
@@ -2,9 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './conversation';
6
5
  export * from './functions';
6
+ export * from './request';
7
7
  export * from './session';
8
8
  export * from './templates';
9
- export * from './types';
10
- export * from './errors';
9
+ export * from './util';