@modelprofile.com/flexharness 10.17.1 → 10.19.0

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 (108) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/errors.d.ts +4 -0
  3. package/dist_ts/errors.js +9 -1
  4. package/dist_ts/functions.toolpermissions.d.ts +24 -0
  5. package/dist_ts/functions.toolpermissions.js +38 -0
  6. package/dist_ts/index.d.ts +1 -0
  7. package/dist_ts/index.js +2 -1
  8. package/dist_ts/plugins.d.ts +1 -1
  9. package/dist_ts/plugins.js +1 -1
  10. package/dist_ts_chat_harness/classes.chatclient.d.ts +95 -0
  11. package/dist_ts_chat_harness/classes.chatclient.js +263 -0
  12. package/dist_ts_chat_harness/classes.chatrequesterror.d.ts +4 -0
  13. package/dist_ts_chat_harness/classes.chatrequesterror.js +8 -0
  14. package/dist_ts_chat_harness/classes.transcript.d.ts +1 -1
  15. package/dist_ts_chat_harness/classes.transcript.js +1 -1
  16. package/dist_ts_chat_harness/functions.intents.d.ts +1 -2
  17. package/dist_ts_chat_harness/functions.intents.js +1 -1
  18. package/dist_ts_chat_harness/functions.mapping.d.ts +1 -1
  19. package/dist_ts_chat_harness/functions.mapping.js +1 -1
  20. package/dist_ts_chat_harness/index.d.ts +3 -0
  21. package/dist_ts_chat_harness/index.js +3 -1
  22. package/dist_ts_chat_harness/interfaces.chat.d.ts +136 -0
  23. package/dist_ts_chat_harness/interfaces.chat.js +2 -0
  24. package/dist_ts_chat_harness/plugins.js +1 -1
  25. package/dist_ts_chat_harness_server/classes.chathub.d.ts +78 -0
  26. package/dist_ts_chat_harness_server/classes.chathub.js +332 -0
  27. package/dist_ts_chat_harness_server/classes.chatsubscription.d.ts +55 -0
  28. package/dist_ts_chat_harness_server/classes.chatsubscription.js +236 -0
  29. package/dist_ts_chat_harness_server/classes.sessionlists.d.ts +21 -0
  30. package/dist_ts_chat_harness_server/classes.sessionlists.js +70 -0
  31. package/dist_ts_chat_harness_server/classes.turngate.d.ts +38 -0
  32. package/dist_ts_chat_harness_server/classes.turngate.js +207 -0
  33. package/dist_ts_chat_harness_server/errors.d.ts +5 -0
  34. package/dist_ts_chat_harness_server/errors.js +9 -0
  35. package/dist_ts_chat_harness_server/functions.errorprojector.d.ts +11 -0
  36. package/dist_ts_chat_harness_server/functions.errorprojector.js +32 -0
  37. package/dist_ts_chat_harness_server/functions.validation.d.ts +18 -0
  38. package/dist_ts_chat_harness_server/functions.validation.js +88 -0
  39. package/dist_ts_chat_harness_server/index.d.ts +4 -0
  40. package/dist_ts_chat_harness_server/index.js +4 -0
  41. package/dist_ts_chat_harness_server/interfaces.d.ts +67 -0
  42. package/dist_ts_chat_harness_server/interfaces.js +2 -0
  43. package/dist_ts_chat_harness_server/plugins.d.ts +7 -0
  44. package/dist_ts_chat_harness_server/plugins.js +6 -0
  45. package/dist_ts_chat_harness_typedsocket/classes.clienttransport.d.ts +22 -0
  46. package/dist_ts_chat_harness_typedsocket/classes.clienttransport.js +55 -0
  47. package/dist_ts_chat_harness_typedsocket/classes.serverbinding.d.ts +46 -0
  48. package/dist_ts_chat_harness_typedsocket/classes.serverbinding.js +110 -0
  49. package/dist_ts_chat_harness_typedsocket/index.d.ts +3 -0
  50. package/dist_ts_chat_harness_typedsocket/index.js +3 -0
  51. package/dist_ts_chat_harness_typedsocket/interfaces.requests.d.ts +38 -0
  52. package/dist_ts_chat_harness_typedsocket/interfaces.requests.js +2 -0
  53. package/dist_ts_chat_harness_typedsocket/plugins.d.ts +9 -0
  54. package/dist_ts_chat_harness_typedsocket/plugins.js +8 -0
  55. package/dist_ts_ocr/ocr.mistral.d.ts +20 -1
  56. package/dist_ts_ocr/ocr.mistral.js +66 -43
  57. package/dist_ts_tools/tool.filesystem.d.ts +2 -0
  58. package/dist_ts_tools/tool.filesystem.js +42 -1
  59. package/dist_ts_tools_node/classes.workspacereversion.d.ts +48 -0
  60. package/dist_ts_tools_node/classes.workspacereversion.js +202 -0
  61. package/dist_ts_tools_node/functions.fileimages.d.ts +22 -0
  62. package/dist_ts_tools_node/functions.fileimages.js +87 -0
  63. package/dist_ts_tools_node/index.d.ts +3 -1
  64. package/dist_ts_tools_node/index.js +2 -1
  65. package/dist_ts_tools_node/plugins.d.ts +1 -0
  66. package/dist_ts_tools_node/tool.context.d.ts +20 -0
  67. package/dist_ts_tools_node/tool.context.js +25 -4
  68. package/package.json +28 -4
  69. package/ts/00_commitinfo_data.ts +1 -1
  70. package/ts/errors.ts +10 -0
  71. package/ts/functions.toolpermissions.ts +60 -0
  72. package/ts/index.ts +6 -0
  73. package/ts/plugins.ts +1 -0
  74. package/ts_chat_harness/classes.chatclient.ts +343 -0
  75. package/ts_chat_harness/classes.chatrequesterror.ts +7 -0
  76. package/ts_chat_harness/classes.transcript.ts +1 -1
  77. package/ts_chat_harness/functions.intents.ts +2 -2
  78. package/ts_chat_harness/functions.mapping.ts +1 -1
  79. package/ts_chat_harness/index.ts +20 -0
  80. package/ts_chat_harness/interfaces.chat.ts +108 -0
  81. package/ts_chat_harness/readme.md +24 -0
  82. package/ts_chat_harness_server/classes.chathub.ts +400 -0
  83. package/ts_chat_harness_server/classes.chatsubscription.ts +257 -0
  84. package/ts_chat_harness_server/classes.sessionlists.ts +90 -0
  85. package/ts_chat_harness_server/classes.turngate.ts +247 -0
  86. package/ts_chat_harness_server/errors.ts +9 -0
  87. package/ts_chat_harness_server/functions.errorprojector.ts +40 -0
  88. package/ts_chat_harness_server/functions.validation.ts +104 -0
  89. package/ts_chat_harness_server/index.ts +19 -0
  90. package/ts_chat_harness_server/interfaces.ts +92 -0
  91. package/ts_chat_harness_server/plugins.ts +62 -0
  92. package/ts_chat_harness_server/readme.md +91 -0
  93. package/ts_chat_harness_typedsocket/classes.clienttransport.ts +87 -0
  94. package/ts_chat_harness_typedsocket/classes.serverbinding.ts +172 -0
  95. package/ts_chat_harness_typedsocket/index.ts +17 -0
  96. package/ts_chat_harness_typedsocket/interfaces.requests.ts +40 -0
  97. package/ts_chat_harness_typedsocket/plugins.ts +28 -0
  98. package/ts_chat_harness_typedsocket/readme.md +57 -0
  99. package/ts_ocr/ocr.mistral.ts +102 -49
  100. package/ts_ocr/readme.md +12 -1
  101. package/ts_tools/readme.md +10 -0
  102. package/ts_tools/tool.filesystem.ts +55 -0
  103. package/ts_tools_node/classes.workspacereversion.ts +255 -0
  104. package/ts_tools_node/functions.fileimages.ts +89 -0
  105. package/ts_tools_node/index.ts +7 -1
  106. package/ts_tools_node/plugins.ts +11 -0
  107. package/ts_tools_node/readme.md +27 -0
  108. package/ts_tools_node/tool.context.ts +49 -3
@@ -0,0 +1,7 @@
1
+ import { FlexHarnessClosedError, FlexHarnessError, FlexHarnessNotFoundError, FlexHarnessSteerRejectedError, FlexHarnessValidationError, modelLimitErrorInfo } from '@modelprofile.com/flexharness';
2
+ import { FlexHarnessChatRequestError, FlexHarnessTranscript, flexHarnessSendIntent, flexSessionToHarnessMeta } from '@modelprofile.com/flexharness/chat/harness';
3
+ import { describeModelFailure } from '@modelprofile.com/flexharness-models';
4
+ export { FlexHarnessChatRequestError, FlexHarnessClosedError, FlexHarnessError, FlexHarnessNotFoundError, FlexHarnessSteerRejectedError, FlexHarnessTranscript, FlexHarnessValidationError, describeModelFailure, flexHarnessSendIntent, flexSessionToHarnessMeta, modelLimitErrorInfo, };
5
+ export type { FlexHarness, IFlexErrorInfo, IFlexExternalErrorContext, IFlexPromptQueueAdmission, IFlexSession, IFlexSessionCreatedEvent, IFlexSessionDeletedEvent, IFlexSessionUpdatedEvent, TFlexExternalErrorProjector, TFlexHarnessEvent, TJsonValue, } from '@modelprofile.com/flexharness';
6
+ export type { IFlexHarnessChatHistoryState, IFlexHarnessChatMethods, IFlexHarnessChatSessionsPush, IFlexHarnessChatSteerOutcome, IFlexHarnessChatToolRequest, IFlexHarnessChatUpdate, TFlexHarnessChatRequest, TFlexHarnessChatResponse, } from '@modelprofile.com/flexharness/chat/harness';
7
+ export type { IHarnessAttachment, IHarnessComposerSendDetail, IHarnessMessage, IHarnessSessionMeta, THarnessStreamDelta, } from '@design.estate/dees-catalog';
@@ -0,0 +1,6 @@
1
+ // @modelprofile.com scope
2
+ import { FlexHarnessClosedError, FlexHarnessError, FlexHarnessNotFoundError, FlexHarnessSteerRejectedError, FlexHarnessValidationError, modelLimitErrorInfo, } from '@modelprofile.com/flexharness';
3
+ import { FlexHarnessChatRequestError, FlexHarnessTranscript, flexHarnessSendIntent, flexSessionToHarnessMeta, } from '@modelprofile.com/flexharness/chat/harness';
4
+ import { describeModelFailure } from '@modelprofile.com/flexharness-models';
5
+ export { FlexHarnessChatRequestError, FlexHarnessClosedError, FlexHarnessError, FlexHarnessNotFoundError, FlexHarnessSteerRejectedError, FlexHarnessTranscript, FlexHarnessValidationError, describeModelFailure, flexHarnessSendIntent, flexSessionToHarnessMeta, modelLimitErrorInfo, };
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2NoYXRfaGFybmVzc19zZXJ2ZXIvcGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwwQkFBMEI7QUFDMUIsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLDZCQUE2QixFQUM3QiwwQkFBMEIsRUFDMUIsbUJBQW1CLEdBQ3BCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUNMLDJCQUEyQixFQUMzQixxQkFBcUIsRUFDckIscUJBQXFCLEVBQ3JCLHdCQUF3QixHQUN6QixNQUFNLDRDQUE0QyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBRTVFLE9BQU8sRUFDTCwyQkFBMkIsRUFDM0Isc0JBQXNCLEVBQ3RCLGdCQUFnQixFQUNoQix3QkFBd0IsRUFDeEIsNkJBQTZCLEVBQzdCLHFCQUFxQixFQUNyQiwwQkFBMEIsRUFDMUIsb0JBQW9CLEVBQ3BCLHFCQUFxQixFQUNyQix3QkFBd0IsRUFDeEIsbUJBQW1CLEdBQ3BCLENBQUMifQ==
@@ -0,0 +1,22 @@
1
+ import * as plugins from './plugins.js';
2
+ export interface IFlexHarnessChatTypedSocketTransportOptions {
3
+ /** The tab's TypedSocket client. */
4
+ typedsocket: plugins.typedsocket.TypedSocket;
5
+ /** The router the client was created with; the transport adds its push handlers to it. */
6
+ typedrouter: plugins.typedrequest.TypedRouter;
7
+ /** The tab: 16 random bytes in hex. Defaults to a new random id for this transport's lifetime. */
8
+ tabId?: string;
9
+ /** The opaque credential the server's `resolve` reads, read for every request. */
10
+ callerToken?: () => string | undefined;
11
+ }
12
+ /** A `FlexHarnessChatClient` transport over the tab's TypedSocket client. */
13
+ export declare class FlexHarnessChatTypedSocketTransport implements plugins.IFlexHarnessChatClientTransport {
14
+ readonly tabId: string;
15
+ private readonly socket;
16
+ private readonly router;
17
+ private readonly callerToken;
18
+ constructor(optionsArg: IFlexHarnessChatTypedSocketTransportOptions);
19
+ request<TMethod extends plugins.TFlexHarnessChatMethod>(methodArg: TMethod, requestArg: plugins.TFlexHarnessChatRequest<TMethod>): Promise<plugins.TFlexHarnessChatResponse<TMethod>>;
20
+ listen(handlersArg: plugins.IFlexHarnessChatPushHandlers): () => void;
21
+ onReconnect(callbackArg: () => void): () => void;
22
+ }
@@ -0,0 +1,55 @@
1
+ import * as plugins from './plugins.js';
2
+ /** 128 random bits as hex; `getRandomValues` works on plain http too, unlike `randomUUID`. */
3
+ const randomTabId = () => Array.from(globalThis.crypto.getRandomValues(new Uint8Array(16)), (byte) => byte.toString(16).padStart(2, '0')).join('');
4
+ /** A `FlexHarnessChatClient` transport over the tab's TypedSocket client. */
5
+ export class FlexHarnessChatTypedSocketTransport {
6
+ tabId;
7
+ socket;
8
+ router;
9
+ callerToken;
10
+ constructor(optionsArg) {
11
+ this.socket = optionsArg.typedsocket;
12
+ this.router = optionsArg.typedrouter;
13
+ this.tabId = optionsArg.tabId ?? randomTabId();
14
+ this.callerToken = optionsArg.callerToken ?? (() => undefined);
15
+ }
16
+ async request(methodArg, requestArg) {
17
+ const token = this.callerToken();
18
+ return this.socket.createTypedRequest(methodArg).fire({
19
+ ...requestArg,
20
+ caller: { tabId: this.tabId, ...(token === undefined ? {} : { token }) },
21
+ });
22
+ }
23
+ listen(handlersArg) {
24
+ const pushes = new plugins.typedrequest.TypedRouter();
25
+ pushes.addTypedHandler(new plugins.typedrequest.TypedHandler('flexHarnessChatUpdate', async (pushArg) => {
26
+ handlersArg.update(pushArg);
27
+ return {};
28
+ }));
29
+ pushes.addTypedHandler(new plugins.typedrequest.TypedHandler('flexHarnessChatSessions', async (pushArg) => {
30
+ handlersArg.sessions(pushArg);
31
+ return {};
32
+ }));
33
+ pushes.addTypedHandler(new plugins.typedrequest.TypedHandler('flexHarnessChatTool', async (requestArg, toolsArg) => ({
34
+ // the server cancels the request when the turn stops or the call times out; the handler then
35
+ // settles at once, since TypedSocket fails a connection whose handlers outlive their requests
36
+ output: await handlersArg.tool(requestArg, toolsArg?.abortSignal),
37
+ })));
38
+ return this.router.addTypedRouter(pushes);
39
+ }
40
+ onReconnect(callbackArg) {
41
+ let wasConnected = true;
42
+ const subscription = this.socket.statusSubject.subscribe((statusArg) => {
43
+ if (statusArg !== 'connected') {
44
+ wasConnected = false;
45
+ return;
46
+ }
47
+ if (wasConnected)
48
+ return;
49
+ wasConnected = true;
50
+ callbackArg();
51
+ });
52
+ return () => subscription.unsubscribe();
53
+ }
54
+ }
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jbGllbnR0cmFuc3BvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19jaGF0X2hhcm5lc3NfdHlwZWRzb2NrZXQvY2xhc3Nlcy5jbGllbnR0cmFuc3BvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFtQnhDLDhGQUE4RjtBQUM5RixNQUFNLFdBQVcsR0FBRyxHQUFXLEVBQUUsQ0FDL0IsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7QUFFM0gsNkVBQTZFO0FBQzdFLE1BQU0sT0FBTyxtQ0FBbUM7SUFDOUIsS0FBSyxDQUFTO0lBRWIsTUFBTSxDQUFrQztJQUN4QyxNQUFNLENBQW1DO0lBQ3pDLFdBQVcsQ0FBMkI7SUFFdkQsWUFBWSxVQUF1RDtRQUNqRSxJQUFJLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUM7UUFDckMsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQyxXQUFXLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRU0sS0FBSyxDQUFDLE9BQU8sQ0FDbEIsU0FBa0IsRUFDbEIsVUFBb0Q7UUFFcEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBZ0MsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ25GLEdBQUcsVUFBVTtZQUNiLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRTtTQUN6RSxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sTUFBTSxDQUFDLFdBQWlEO1FBQzdELE1BQU0sTUFBTSxHQUFHLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN0RCxNQUFNLENBQUMsZUFBZSxDQUNwQixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUE2Qix1QkFBdUIsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7WUFDM0csV0FBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM1QixPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixNQUFNLENBQUMsZUFBZSxDQUNwQixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUErQix5QkFBeUIsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7WUFDL0csV0FBVyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM5QixPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixNQUFNLENBQUMsZUFBZSxDQUNwQixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUEyQixxQkFBcUIsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0SCw2RkFBNkY7WUFDN0YsOEZBQThGO1lBQzlGLE1BQU0sRUFBRSxNQUFNLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFFBQVEsRUFBRSxXQUFXLENBQUM7U0FDbEUsQ0FBQyxDQUFDLENBQ0osQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVNLFdBQVcsQ0FBQyxXQUF1QjtRQUN4QyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDeEIsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDckUsSUFBSSxTQUFTLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQzlCLFlBQVksR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxZQUFZO2dCQUFFLE9BQU87WUFDekIsWUFBWSxHQUFHLElBQUksQ0FBQztZQUNwQixXQUFXLEVBQUUsQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQzFDLENBQUM7Q0FDRiJ9
@@ -0,0 +1,46 @@
1
+ import * as plugins from './plugins.js';
2
+ import type { IFlexHarnessChatCallerPayload } from './interfaces.requests.js';
3
+ /** The hub requests the binding routes; any `FlexHarnessChatHub` serves them. */
4
+ export type TFlexHarnessChatRequestHandler = Pick<plugins.FlexHarnessChatHub<unknown>, 'attach' | 'open' | 'close' | 'send' | 'abort' | 'respondToPermission' | 'moveHistory' | 'renameSession' | 'deleteSession'>;
5
+ /** The hub and scope a request reaches, as the host established them. */
6
+ export interface IFlexHarnessChatResolvedCaller {
7
+ hub: TFlexHarnessChatRequestHandler;
8
+ scopeId: string;
9
+ }
10
+ export interface IFlexHarnessChatTypedSocketBindingOptions {
11
+ /**
12
+ * Authenticates a request: from the caller payload and the request's TypedSocket context, the hub
13
+ * and the scope it reaches. Throw a `FlexHarnessChatRequestError` to refuse with a message.
14
+ */
15
+ resolve(caller: IFlexHarnessChatCallerPayload, context: plugins.typedsocket.ITypedSocketRequestContext | undefined): Promise<IFlexHarnessChatResolvedCaller>;
16
+ /** The server-owned connection tag that names a tab. Default: `flexHarnessChatTab`. */
17
+ tag?: string;
18
+ /** How long an update or a session-list push may wait for the tab. Default: 30 seconds. */
19
+ pushTimeoutMs?: number;
20
+ }
21
+ /**
22
+ * Serves a `FlexHarnessChatHub` over TypedSocket. Add `typedrouter` to the server's router, hand
23
+ * the server's TypedSocket to `setTypedSocket()` once it runs, and give the hub `peers`. A tab's
24
+ * connection carries the server-owned tag with its tab id; every request claims it again.
25
+ */
26
+ export declare class FlexHarnessChatTypedSocketBinding implements plugins.IFlexHarnessChatPeers {
27
+ readonly typedrouter: plugins.typedrequest.TypedRouter<plugins.typedrequestInterfaces.ITypedRequest>;
28
+ private readonly resolveCaller;
29
+ private readonly tag;
30
+ private readonly pushTimeoutMs;
31
+ private socket;
32
+ constructor(optionsArg: IFlexHarnessChatTypedSocketBindingOptions);
33
+ /** The server's TypedSocket; it exists once the server runs. */
34
+ setTypedSocket(socketArg: plugins.typedsocket.TypedSocket): void;
35
+ /** The tab's current connection in its scope, as the hub reaches it. */
36
+ find(tabArg: plugins.IFlexHarnessChatCaller): Promise<plugins.IFlexHarnessChatPeer | null>;
37
+ private route;
38
+ /** Authenticates a request, claims its connection for the tab and runs it on the resolved hub. */
39
+ private serve;
40
+ /**
41
+ * Marks the connection the request came in on as the tab's, and only that one. The tag names the
42
+ * tab in its resolved scope, so a caller of another scope that sends the same tab id names a tab
43
+ * of its own and never reaches this one's connection.
44
+ */
45
+ private claim;
46
+ }
@@ -0,0 +1,110 @@
1
+ import * as plugins from './plugins.js';
2
+ const TAB_ID_PATTERN = /^[0-9a-f]{32}$/;
3
+ const BAD_REQUEST_MESSAGE = 'The request is malformed. Reload the page and try again.';
4
+ const NOT_READY_MESSAGE = 'The server is not accepting connections yet.';
5
+ /** The tag payload that names a tab: its scope and its id, in a fixed key order. */
6
+ const tagPayload = (tabArg) => ({
7
+ scopeId: tabArg.scopeId,
8
+ tabId: tabArg.tabId,
9
+ });
10
+ class TypedSocketChatPeer {
11
+ socket;
12
+ connection;
13
+ pushTimeoutMs;
14
+ constructor(socket, connection, pushTimeoutMs) {
15
+ this.socket = socket;
16
+ this.connection = connection;
17
+ this.pushTimeoutMs = pushTimeoutMs;
18
+ }
19
+ async update(pushArg) {
20
+ await this.socket
21
+ .createTypedRequest('flexHarnessChatUpdate', this.connection, { timeoutMs: this.pushTimeoutMs })
22
+ .fire(pushArg);
23
+ }
24
+ async sessions(pushArg) {
25
+ await this.socket
26
+ .createTypedRequest('flexHarnessChatSessions', this.connection, { timeoutMs: this.pushTimeoutMs })
27
+ .fire(pushArg);
28
+ }
29
+ async runTool(requestArg, optionsArg) {
30
+ const answer = await this.socket
31
+ .createTypedRequest('flexHarnessChatTool', this.connection, optionsArg)
32
+ .fire(requestArg);
33
+ return answer.output;
34
+ }
35
+ }
36
+ /**
37
+ * Serves a `FlexHarnessChatHub` over TypedSocket. Add `typedrouter` to the server's router, hand
38
+ * the server's TypedSocket to `setTypedSocket()` once it runs, and give the hub `peers`. A tab's
39
+ * connection carries the server-owned tag with its tab id; every request claims it again.
40
+ */
41
+ export class FlexHarnessChatTypedSocketBinding {
42
+ typedrouter = new plugins.typedrequest.TypedRouter();
43
+ resolveCaller;
44
+ tag;
45
+ pushTimeoutMs;
46
+ socket = null;
47
+ constructor(optionsArg) {
48
+ this.resolveCaller = optionsArg.resolve;
49
+ this.tag = optionsArg.tag ?? 'flexHarnessChatTab';
50
+ this.pushTimeoutMs = optionsArg.pushTimeoutMs ?? 30 * 1000;
51
+ this.route('flexHarnessChatAttach', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.attach(caller)));
52
+ this.route('flexHarnessChatOpen', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.open(caller, request)));
53
+ this.route('flexHarnessChatClose', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.close(caller, request)));
54
+ this.route('flexHarnessChatSend', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.send(caller, request)));
55
+ this.route('flexHarnessChatAbort', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.abort(caller, request)));
56
+ this.route('flexHarnessChatPermission', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.respondToPermission(caller, request)));
57
+ this.route('flexHarnessChatHistory', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.moveHistory(caller, request)));
58
+ this.route('flexHarnessChatSessionUpdate', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.renameSession(caller, request)));
59
+ this.route('flexHarnessChatSessionDelete', (request, tools) => this.serve(request.caller, tools, (hub, caller) => hub.deleteSession(caller, request)));
60
+ }
61
+ /** The server's TypedSocket; it exists once the server runs. */
62
+ setTypedSocket(socketArg) {
63
+ this.socket = socketArg;
64
+ }
65
+ /** The tab's current connection in its scope, as the hub reaches it. */
66
+ async find(tabArg) {
67
+ if (!this.socket)
68
+ return null;
69
+ const connection = await this.socket.findTargetConnectionByTag(this.tag, tagPayload(tabArg));
70
+ return connection ? new TypedSocketChatPeer(this.socket, connection, this.pushTimeoutMs) : null;
71
+ }
72
+ route(methodArg, handlerArg) {
73
+ this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler(methodArg, handlerArg));
74
+ }
75
+ /** Authenticates a request, claims its connection for the tab and runs it on the resolved hub. */
76
+ async serve(payloadArg, contextArg, runArg) {
77
+ try {
78
+ if (!payloadArg || typeof payloadArg.tabId !== 'string' || !TAB_ID_PATTERN.test(payloadArg.tabId)) {
79
+ throw new plugins.FlexHarnessChatRequestError(BAD_REQUEST_MESSAGE);
80
+ }
81
+ const resolved = await this.resolveCaller(payloadArg, contextArg);
82
+ const caller = { tabId: payloadArg.tabId, scopeId: resolved.scopeId };
83
+ await this.claim(contextArg, caller);
84
+ return await runArg(resolved.hub, caller);
85
+ }
86
+ catch (error) {
87
+ if (error instanceof plugins.FlexHarnessChatRequestError) {
88
+ throw new plugins.typedrequest.TypedResponseError(error.message);
89
+ }
90
+ throw error;
91
+ }
92
+ }
93
+ /**
94
+ * Marks the connection the request came in on as the tab's, and only that one. The tag names the
95
+ * tab in its resolved scope, so a caller of another scope that sends the same tab id names a tab
96
+ * of its own and never reaches this one's connection.
97
+ */
98
+ async claim(contextArg, tabArg) {
99
+ if (!this.socket)
100
+ throw new plugins.FlexHarnessChatRequestError(NOT_READY_MESSAGE);
101
+ const connection = this.socket.getServerConnectionForRequest(contextArg);
102
+ const payload = tagPayload(tabArg);
103
+ for (const other of await this.socket.findAllTargetConnectionsByTag(this.tag, payload)) {
104
+ if (other.peer !== connection.peer)
105
+ this.socket.removeServerTag(other, this.tag);
106
+ }
107
+ this.socket.setServerTag(connection, this.tag, payload);
108
+ }
109
+ }
110
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zZXJ2ZXJiaW5kaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfY2hhdF9oYXJuZXNzX3R5cGVkc29ja2V0L2NsYXNzZXMuc2VydmVyYmluZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQW9DeEMsTUFBTSxjQUFjLEdBQUcsZ0JBQWdCLENBQUM7QUFDeEMsTUFBTSxtQkFBbUIsR0FBRywwREFBMEQsQ0FBQztBQUN2RixNQUFNLGlCQUFpQixHQUFHLDhDQUE4QyxDQUFDO0FBRXpFLG9GQUFvRjtBQUNwRixNQUFNLFVBQVUsR0FBRyxDQUFDLE1BQXNDLEVBQXNDLEVBQUUsQ0FBQyxDQUFDO0lBQ2xHLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztJQUN2QixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7Q0FDcEIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxtQkFBbUI7SUFFSjtJQUNBO0lBQ0E7SUFIbkIsWUFDbUIsTUFBdUMsRUFDdkMsVUFBNEQsRUFDNUQsYUFBcUI7UUFGckIsV0FBTSxHQUFOLE1BQU0sQ0FBaUM7UUFDdkMsZUFBVSxHQUFWLFVBQVUsQ0FBa0Q7UUFDNUQsa0JBQWEsR0FBYixhQUFhLENBQVE7SUFDckMsQ0FBQztJQUVHLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBdUM7UUFDekQsTUFBTSxJQUFJLENBQUMsTUFBTTthQUNkLGtCQUFrQixDQUE2Qix1QkFBdUIsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUMzSCxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQUVNLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBNkM7UUFDakUsTUFBTSxJQUFJLENBQUMsTUFBTTthQUNkLGtCQUFrQixDQUErQix5QkFBeUIsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFF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
@@ -0,0 +1,3 @@
1
+ export { FlexHarnessChatTypedSocketBinding, type IFlexHarnessChatResolvedCaller, type IFlexHarnessChatTypedSocketBindingOptions, type TFlexHarnessChatRequestHandler, } from './classes.serverbinding.js';
2
+ export { FlexHarnessChatTypedSocketTransport, type IFlexHarnessChatTypedSocketTransportOptions, } from './classes.clienttransport.js';
3
+ export type { IFlexHarnessChatCallerPayload, IReq_FlexHarnessChat, IReq_FlexHarnessChatSessions, IReq_FlexHarnessChatTool, IReq_FlexHarnessChatUpdate, } from './interfaces.requests.js';
@@ -0,0 +1,3 @@
1
+ export { FlexHarnessChatTypedSocketBinding, } from './classes.serverbinding.js';
2
+ export { FlexHarnessChatTypedSocketTransport, } from './classes.clienttransport.js';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19jaGF0X2hhcm5lc3NfdHlwZWRzb2NrZXQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGlDQUFpQyxHQUlsQyxNQUFNLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sRUFDTCxtQ0FBbUMsR0FFcEMsTUFBTSw4QkFBOEIsQ0FBQyJ9
@@ -0,0 +1,38 @@
1
+ import type * as plugins from './plugins.js';
2
+ /** Who sends a request: the tab, and an opaque credential the host's `resolve` reads. */
3
+ export interface IFlexHarnessChatCallerPayload {
4
+ /**
5
+ * The tab: 16 random bytes in hex, kept for the tab's lifetime and never shared. Every request
6
+ * claims the connection it arrives on for the tab, so pushes and tool calls follow a reconnect.
7
+ */
8
+ tabId: string;
9
+ token?: string;
10
+ }
11
+ /** A tab's request to the hub over TypedSocket. */
12
+ export interface IReq_FlexHarnessChat<TMethod extends plugins.TFlexHarnessChatMethod> extends plugins.typedrequestInterfaces.ITypedRequest {
13
+ method: TMethod;
14
+ request: plugins.TFlexHarnessChatRequest<TMethod> & {
15
+ caller: IFlexHarnessChatCallerPayload;
16
+ };
17
+ response: plugins.TFlexHarnessChatResponse<TMethod>;
18
+ }
19
+ /** Push: what changed in the conversation a tab follows. */
20
+ export interface IReq_FlexHarnessChatUpdate extends plugins.typedrequestInterfaces.ITypedRequest {
21
+ method: 'flexHarnessChatUpdate';
22
+ request: plugins.IFlexHarnessChatUpdate;
23
+ response: Record<string, never>;
24
+ }
25
+ /** Push: changes of the tab's conversation list. */
26
+ export interface IReq_FlexHarnessChatSessions extends plugins.typedrequestInterfaces.ITypedRequest {
27
+ method: 'flexHarnessChatSessions';
28
+ request: plugins.IFlexHarnessChatSessionsPush;
29
+ response: Record<string, never>;
30
+ }
31
+ /** Push: run a tool of a turn in the tab; the answer is the tool's output. */
32
+ export interface IReq_FlexHarnessChatTool extends plugins.typedrequestInterfaces.ITypedRequest {
33
+ method: 'flexHarnessChatTool';
34
+ request: plugins.IFlexHarnessChatToolRequest;
35
+ response: {
36
+ output: plugins.TJsonValue;
37
+ };
38
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5yZXF1ZXN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2NoYXRfaGFybmVzc190eXBlZHNvY2tldC9pbnRlcmZhY2VzLnJlcXVlc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,9 @@
1
+ import * as typedrequest from '@api.global/typedrequest';
2
+ import * as typedsocket from '@api.global/typedsocket';
3
+ export { typedrequest, typedsocket };
4
+ export type * as typedrequestInterfaces from '@api.global/typedrequest-interfaces';
5
+ import { FlexHarnessChatRequestError } from '@modelprofile.com/flexharness/chat/harness';
6
+ export { FlexHarnessChatRequestError };
7
+ export type { TJsonValue } from '@modelprofile.com/flexharness';
8
+ export type { IFlexHarnessChatClientTransport, IFlexHarnessChatPushHandlers, IFlexHarnessChatSessionsPush, IFlexHarnessChatToolRequest, IFlexHarnessChatUpdate, TFlexHarnessChatMethod, TFlexHarnessChatRequest, TFlexHarnessChatResponse, } from '@modelprofile.com/flexharness/chat/harness';
9
+ export type { FlexHarnessChatHub, IFlexHarnessChatCaller, IFlexHarnessChatPeer, IFlexHarnessChatPeers, } from '@modelprofile.com/flexharness/chat/harness/server';
@@ -0,0 +1,8 @@
1
+ // @api.global scope
2
+ import * as typedrequest from '@api.global/typedrequest';
3
+ import * as typedsocket from '@api.global/typedsocket';
4
+ export { typedrequest, typedsocket };
5
+ // @modelprofile.com scope
6
+ import { FlexHarnessChatRequestError } from '@modelprofile.com/flexharness/chat/harness';
7
+ export { FlexHarnessChatRequestError };
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2NoYXRfaGFybmVzc190eXBlZHNvY2tldC9wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9CQUFvQjtBQUNwQixPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFFdkQsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsQ0FBQztBQUdyQywwQkFBMEI7QUFDMUIsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFFekYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLENBQUMifQ==
@@ -5,6 +5,12 @@ export interface ISmartAiOcrImageInput {
5
5
  dataBase64: string;
6
6
  mimeType: TSmartAiOcrImageMimeType;
7
7
  }
8
+ /** Mistral OCR reads PDF, PPTX, DOCX and other document formats. */
9
+ export type TSmartAiOcrDocumentMimeType = 'application/pdf' | 'application/vnd.openxmlformats-officedocument.presentationml.presentation' | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' | string;
10
+ export interface ISmartAiOcrDocumentInput {
11
+ dataBase64: string;
12
+ mimeType: TSmartAiOcrDocumentMimeType;
13
+ }
8
14
  export interface ISmartAiOcrPageResult {
9
15
  index: number;
10
16
  text: string;
@@ -19,6 +25,10 @@ export interface ISmartAiOcrResult<TRaw = unknown> {
19
25
  export interface ISmartAiOcrEngine {
20
26
  recognizeImage: (input: ISmartAiOcrImageInput, options?: ISmartAiMistralOcrRecognizeOptions) => Promise<ISmartAiOcrResult<IMistralOcrResponse>>;
21
27
  }
28
+ /** The Mistral OCR engine also reads whole documents, such as a PDF with all its pages. */
29
+ export interface ISmartAiMistralOcrEngine extends ISmartAiOcrEngine {
30
+ recognizeDocument: (input: ISmartAiOcrDocumentInput, options?: ISmartAiMistralOcrRecognizeOptions) => Promise<ISmartAiOcrResult<IMistralOcrResponse>>;
31
+ }
22
32
  export interface IMistralOcrPageConfidenceScores {
23
33
  average_page_confidence_score?: number;
24
34
  averagePageConfidenceScore?: number;
@@ -51,8 +61,17 @@ export interface IMistralOcrRequest {
51
61
  extract_footer?: boolean;
52
62
  confidence_scores_granularity?: TSmartAiMistralOcrConfidenceScoresGranularity;
53
63
  }
64
+ /** A document (PDF, PPTX, DOCX and other formats) as a URL or a base64 data URL; the other fields are those of an image request. */
65
+ export interface IMistralOcrDocumentRequest extends Omit<IMistralOcrRequest, 'document'> {
66
+ document: {
67
+ type: 'document_url';
68
+ document_url: string;
69
+ };
70
+ }
54
71
  export interface ISmartAiMistralOcrTransport {
55
72
  process: (request: IMistralOcrRequest) => Promise<IMistralOcrResponse>;
73
+ /** Reads documents. A transport without it reads images only, and `recognizeDocument` refuses documents. */
74
+ processDocument?: (request: IMistralOcrDocumentRequest) => Promise<IMistralOcrResponse>;
56
75
  }
57
76
  export interface ISmartAiMistralOcrOptions {
58
77
  apiKey?: string;
@@ -72,4 +91,4 @@ export interface ISmartAiMistralOcrRecognizeOptions {
72
91
  extractFooter?: boolean;
73
92
  confidenceScoresGranularity?: TSmartAiMistralOcrConfidenceScoresGranularity;
74
93
  }
75
- export declare const createMistralOcrEngine: (options?: ISmartAiMistralOcrOptions) => ISmartAiOcrEngine;
94
+ export declare const createMistralOcrEngine: (options?: ISmartAiMistralOcrOptions) => ISmartAiMistralOcrEngine;
@@ -1,32 +1,50 @@
1
1
  const defaultMistralOcrModel = 'mistral-ocr-latest';
2
2
  const defaultMistralOcrEndpointUrl = 'https://api.mistral.ai/v1/ocr';
3
3
  const createMistralOcrHttpTransport = (options) => {
4
- return {
5
- process: async (request) => {
6
- if (!options.apiKey) {
7
- throw new Error('Mistral OCR requires an apiKey when no custom transport is provided.');
8
- }
9
- const response = await fetch(options.endpointUrl ?? defaultMistralOcrEndpointUrl, {
10
- method: 'POST',
11
- headers: {
12
- Authorization: `Bearer ${options.apiKey}`,
13
- 'Content-Type': 'application/json',
14
- },
15
- body: JSON.stringify(request),
16
- });
17
- if (!response.ok) {
18
- const errorBody = await response.text();
19
- throw new Error(`Mistral OCR request failed with status ${response.status}: ${errorBody}`);
20
- }
21
- return (await response.json());
22
- },
4
+ const post = async (request) => {
5
+ if (!options.apiKey) {
6
+ throw new Error('Mistral OCR requires an apiKey when no custom transport is provided.');
7
+ }
8
+ const response = await fetch(options.endpointUrl ?? defaultMistralOcrEndpointUrl, {
9
+ method: 'POST',
10
+ headers: {
11
+ Authorization: `Bearer ${options.apiKey}`,
12
+ 'Content-Type': 'application/json',
13
+ },
14
+ body: JSON.stringify(request),
15
+ });
16
+ if (!response.ok) {
17
+ const errorBody = await response.text();
18
+ throw new Error(`Mistral OCR request failed with status ${response.status}: ${errorBody}`);
19
+ }
20
+ return (await response.json());
23
21
  };
22
+ return { process: post, processDocument: post };
24
23
  };
25
24
  const getPageConfidence = (page) => {
26
25
  const confidenceScores = page.confidence_scores ?? page.confidenceScores;
27
26
  return (confidenceScores?.average_page_confidence_score ??
28
27
  confidenceScores?.averagePageConfidenceScore);
29
28
  };
29
+ const toOcrResult = (response) => {
30
+ const pages = response.pages.map((page) => ({
31
+ index: page.index,
32
+ text: page.markdown,
33
+ confidence: getPageConfidence(page),
34
+ }));
35
+ const pageConfidences = pages
36
+ .map((page) => page.confidence)
37
+ .filter((confidence) => typeof confidence === 'number');
38
+ const confidence = pageConfidences.length
39
+ ? pageConfidences.reduce((sum, value) => sum + value, 0) / pageConfidences.length
40
+ : undefined;
41
+ return {
42
+ text: pages.map((page) => page.text).join('\n\n').trim(),
43
+ confidence,
44
+ pages,
45
+ raw: response,
46
+ };
47
+ };
30
48
  export const createMistralOcrEngine = (options = {}) => {
31
49
  const transport = options.transport ??
32
50
  createMistralOcrHttpTransport({
@@ -34,6 +52,13 @@ export const createMistralOcrEngine = (options = {}) => {
34
52
  endpointUrl: options.endpointUrl,
35
53
  });
36
54
  const model = options.model ?? defaultMistralOcrModel;
55
+ const settingsOf = (recognizeOptions) => ({
56
+ include_image_base64: recognizeOptions.includeImageBase64 ?? options.includeImageBase64 ?? false,
57
+ table_format: recognizeOptions.tableFormat ?? options.tableFormat,
58
+ extract_header: recognizeOptions.extractHeader ?? options.extractHeader,
59
+ extract_footer: recognizeOptions.extractFooter ?? options.extractFooter,
60
+ confidence_scores_granularity: recognizeOptions.confidenceScoresGranularity ?? options.confidenceScoresGranularity,
61
+ });
37
62
  return {
38
63
  recognizeImage: async (input, recognizeOptions = {}) => {
39
64
  if (!input.dataBase64) {
@@ -42,36 +67,34 @@ export const createMistralOcrEngine = (options = {}) => {
42
67
  if (!input.mimeType) {
43
68
  throw new Error('Mistral OCR image input requires mimeType.');
44
69
  }
45
- const response = await transport.process({
70
+ return toOcrResult(await transport.process({
46
71
  model,
47
72
  document: {
48
73
  type: 'image_url',
49
74
  image_url: `data:${input.mimeType};base64,${input.dataBase64}`,
50
75
  },
51
- include_image_base64: recognizeOptions.includeImageBase64 ?? options.includeImageBase64 ?? false,
52
- table_format: recognizeOptions.tableFormat ?? options.tableFormat,
53
- extract_header: recognizeOptions.extractHeader ?? options.extractHeader,
54
- extract_footer: recognizeOptions.extractFooter ?? options.extractFooter,
55
- confidence_scores_granularity: recognizeOptions.confidenceScoresGranularity ?? options.confidenceScoresGranularity,
56
- });
57
- const pages = response.pages.map((page) => ({
58
- index: page.index,
59
- text: page.markdown,
60
- confidence: getPageConfidence(page),
76
+ ...settingsOf(recognizeOptions),
77
+ }));
78
+ },
79
+ recognizeDocument: async (input, recognizeOptions = {}) => {
80
+ if (!transport.processDocument) {
81
+ throw new Error('This Mistral OCR transport reads images only: it has no processDocument, so it cannot read documents.');
82
+ }
83
+ if (!input.dataBase64) {
84
+ throw new Error('Mistral OCR document input requires dataBase64.');
85
+ }
86
+ if (!input.mimeType) {
87
+ throw new Error('Mistral OCR document input requires mimeType.');
88
+ }
89
+ return toOcrResult(await transport.processDocument({
90
+ model,
91
+ document: {
92
+ type: 'document_url',
93
+ document_url: `data:${input.mimeType};base64,${input.dataBase64}`,
94
+ },
95
+ ...settingsOf(recognizeOptions),
61
96
  }));
62
- const pageConfidences = pages
63
- .map((page) => page.confidence)
64
- .filter((confidence) => typeof confidence === 'number');
65
- const confidence = pageConfidences.length
66
- ? pageConfidences.reduce((sum, value) => sum + value, 0) / pageConfidences.length
67
- : undefined;
68
- return {
69
- text: pages.map((page) => page.text).join('\n\n').trim(),
70
- confidence,
71
- pages,
72
- raw: response,
73
- };
74
97
  },
75
98
  };
76
99
  };
77
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2NyLm1pc3RyYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19vY3Ivb2NyLm1pc3RyYWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBZ0dBLE1BQU0sc0JBQXNCLEdBQUcsb0JBQW9CLENBQUM7QUFDcEQsTUFBTSw0QkFBNEIsR0FBRywrQkFBK0IsQ0FBQztBQUVyRSxNQUFNLDZCQUE2QixHQUFHLENBQUMsT0FHdEMsRUFBK0IsRUFBRTtJQUNoQyxPQUFPO1FBQ0wsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUN6QixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLHNFQUFzRSxDQUFDLENBQUM7WUFDMUYsQ0FBQztZQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLElBQUksNEJBQTRCLEVBQUU7Z0JBQ2hGLE1BQU0sRUFBRSxNQUFNO2dCQUNkLE9BQU8sRUFBRTtvQkFDUCxhQUFhLEVBQUUsVUFBVSxPQUFPLENBQUMsTUFBTSxFQUFFO29CQUN6QyxjQUFjLEVBQUUsa0JBQWtCO2lCQUNuQztnQkFDRCxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUM7YUFDOUIsQ0FBQyxDQUFDO1lBRUgsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxTQUFTLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hDLE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLFFBQVEsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUMsQ0FBQztZQUM3RixDQUFDO1lBRUQsT0FBTyxDQUFDLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBRSxDQUF3QixDQUFDO1FBQ3hELENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUYsTUFBTSxpQkFBaUIsR0FB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
100
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2NyLm1pc3RyYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19vY3Ivb2NyLm1pc3RyYWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBOEhBLE1BQU0sc0JBQXNCLEdBQUcsb0JBQW9CLENBQUM7QUFDcEQsTUFBTSw0QkFBNEIsR0FBRywrQkFBK0IsQ0FBQztBQUVyRSxNQUFNLDZCQUE2QixHQUFHLENBQUMsT0FHdEMsRUFBK0IsRUFBRTtJQUNoQyxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsT0FBd0QsRUFBZ0MsRUFBRTtRQUM1RyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztRQUMxRixDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsSUFBSSw0QkFBNEIsRUFBRTtZQUNoRixNQUFNLEVBQUUsTUFBTTtZQUNkLE9BQU8sRUFBRTtnQkFDUCxhQUFhLEVBQUUsVUFBVSxPQUFPLENBQUMsTUFBTSxFQUFFO2dCQUN6QyxjQUFjLEVBQUUsa0JBQWtCO2FBQ25DO1lBQ0QsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDO1NBQzlCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDakIsTUFBTSxTQUFTLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDeEMsTUFBTSxJQUFJLEtBQUssQ0FBQywwQ0FBMEMsUUFBUSxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzdGLENBQUM7UUFFRCxPQUFPLENBQUMsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQXdCLENBQUM7SUFDeEQsQ0FBQyxDQUFDO0lBQ0YsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLElBQUks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
@@ -3,6 +3,8 @@ import { type IToolExecutionContext } from './tool.context.js';
3
3
  export interface ICreateFilesystemToolsOptions {
4
4
  /** Include delete_file. Default: true. */
5
5
  includeDelete?: boolean;
6
+ /** Include edit_file, which replaces an exact snippet of a file. Default: false. */
7
+ includeEdit?: boolean;
6
8
  /** Maximum output lines before truncating. */
7
9
  maxLines?: number;
8
10
  /** Maximum output bytes before truncating. */