@chelone/core 0.6.0 → 0.9.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.
- package/dist/assistant/assistant-session.d.ts +6 -0
- package/dist/assistant/assistant-session.js +204 -181
- package/dist/assistant/echo-transport.js +26 -29
- package/dist/assistant/http-transport.d.ts +10 -0
- package/dist/assistant/http-transport.js +98 -0
- package/dist/assistant/types.d.ts +1 -7
- package/dist/auth/access-control.d.ts +13 -5
- package/dist/auth/access-control.js +25 -21
- package/dist/auth/auth-options.d.ts +23 -17
- package/dist/auth/auth-options.js +82 -48
- package/dist/auth/permission-matrix.d.ts +12 -0
- package/dist/auth/permission-matrix.js +67 -0
- package/dist/auth/types.d.ts +14 -4
- package/dist/block-editor/block-document.d.ts +64 -0
- package/dist/block-editor/block-document.js +147 -0
- package/dist/block-editor/data-blocks.d.ts +63 -0
- package/dist/block-editor/data-blocks.js +117 -0
- package/dist/chart/chart-data.js +46 -44
- package/dist/command-menu/hotkey.js +58 -47
- package/dist/command-menu/recents.d.ts +4 -0
- package/dist/command-menu/recents.js +12 -11
- package/dist/command-menu/registry.d.ts +9 -5
- package/dist/command-menu/registry.js +36 -46
- package/dist/controller/calendar-dates.d.ts +12 -0
- package/dist/controller/calendar-dates.js +94 -113
- package/dist/controller/calendar-events.js +93 -88
- package/dist/controller/client-list-controller.d.ts +2 -2
- package/dist/controller/client-list-controller.js +251 -254
- package/dist/controller/data-table-columns.d.ts +2 -0
- package/dist/controller/data-table-columns.js +50 -56
- package/dist/controller/deep-equal.d.ts +1 -0
- package/dist/controller/deep-equal.js +14 -0
- package/dist/controller/filter-toggle.js +36 -44
- package/dist/controller/in-place-editor.d.ts +43 -0
- package/dist/controller/in-place-editor.js +43 -0
- package/dist/controller/infinite-list-controller.js +219 -189
- package/dist/controller/inspector.d.ts +55 -0
- package/dist/controller/inspector.js +70 -0
- package/dist/controller/job-monitor.d.ts +10 -4
- package/dist/controller/job-monitor.js +46 -47
- package/dist/controller/kanban-board.js +45 -24
- package/dist/controller/list-controller.d.ts +8 -5
- package/dist/controller/list-controller.js +447 -400
- package/dist/controller/list-params.js +96 -87
- package/dist/controller/pivot-grid.d.ts +4 -4
- package/dist/controller/pivot-grid.js +89 -95
- package/dist/controller/prev-next.d.ts +2 -2
- package/dist/controller/prev-next.js +74 -54
- package/dist/controller/record-controllers.d.ts +14 -6
- package/dist/controller/record-controllers.js +288 -257
- package/dist/controller/record-diff.d.ts +21 -0
- package/dist/controller/record-diff.js +50 -0
- package/dist/controller/record-timeline.d.ts +5 -5
- package/dist/controller/record-timeline.js +42 -30
- package/dist/controller/record-tree.js +57 -47
- package/dist/controller/record-workflow.d.ts +38 -16
- package/dist/controller/record-workflow.js +85 -64
- package/dist/controller/reference-many-controller.d.ts +2 -0
- package/dist/controller/reference-many-controller.js +199 -192
- package/dist/controller/reference-one-controller.d.ts +1 -1
- package/dist/controller/reference-one-controller.js +63 -56
- package/dist/controller/saved-queries.js +104 -91
- package/dist/controller/translate-fallback.js +10 -6
- package/dist/csv/export.d.ts +4 -3
- package/dist/csv/export.js +43 -40
- package/dist/csv/import-controller.d.ts +4 -0
- package/dist/csv/import-controller.js +189 -169
- package/dist/csv/match-headers.js +29 -22
- package/dist/csv/parse-with.js +60 -54
- package/dist/csv/run-import.js +69 -72
- package/dist/csv/validate-rows.d.ts +1 -1
- package/dist/csv/validate-rows.js +65 -52
- package/dist/data/cache-ops.d.ts +5 -4
- package/dist/data/cache-ops.js +208 -188
- package/dist/data/combine-data-providers.js +25 -23
- package/dist/data/data-provider-log.d.ts +45 -0
- package/dist/data/data-provider-log.js +93 -0
- package/dist/data/errors.js +14 -10
- package/dist/data/fake-provider.d.ts +6 -3
- package/dist/data/fake-provider.js +135 -114
- package/dist/data/fetch-utils.js +61 -44
- package/dist/data/filter-branch.d.ts +5 -0
- package/dist/data/filter-branch.js +10 -0
- package/dist/data/get-many-aggregate.js +84 -76
- package/dist/data/http-error.js +17 -12
- package/dist/data/keys.js +50 -36
- package/dist/data/mutation-options.d.ts +14 -9
- package/dist/data/mutation-options.js +93 -109
- package/dist/data/query-options.js +73 -68
- package/dist/data/remove-empty.d.ts +3 -0
- package/dist/data/remove-empty.js +11 -0
- package/dist/data/undoable.d.ts +2 -2
- package/dist/data/undoable.js +190 -174
- package/dist/data/with-lifecycle-callbacks.d.ts +45 -17
- package/dist/data/with-lifecycle-callbacks.js +66 -52
- package/dist/environment/application-update-store.js +58 -55
- package/dist/environment/offline-store.js +21 -21
- package/dist/form/array-binding.d.ts +30 -11
- package/dist/form/array-binding.js +184 -166
- package/dist/form/choice-ids.d.ts +7 -0
- package/dist/form/choice-ids.js +11 -0
- package/dist/form/choices-controller.d.ts +22 -2
- package/dist/form/choices-controller.js +315 -275
- package/dist/form/date-format.d.ts +38 -0
- package/dist/form/date-format.js +89 -0
- package/dist/form/dirty-values.d.ts +2 -2
- package/dist/form/dirty-values.js +22 -11
- package/dist/form/duration.d.ts +22 -0
- package/dist/form/duration.js +49 -0
- package/dist/form/edit-create-form.d.ts +12 -5
- package/dist/form/edit-create-form.js +243 -188
- package/dist/form/event-value.d.ts +6 -0
- package/dist/form/event-value.js +17 -0
- package/dist/form/field-error.d.ts +14 -0
- package/dist/form/field-error.js +28 -0
- package/dist/form/field-name.d.ts +20 -0
- package/dist/form/field-name.js +6 -0
- package/dist/form/filter-form-values.js +63 -49
- package/dist/form/form-controller.d.ts +9 -1
- package/dist/form/form-controller.js +165 -160
- package/dist/form/form-groups.d.ts +4 -3
- package/dist/form/form-groups.js +79 -79
- package/dist/form/form-handle.d.ts +175 -0
- package/dist/form/form-handle.js +68 -0
- package/dist/form/input-binding.d.ts +56 -31
- package/dist/form/input-binding.js +171 -118
- package/dist/form/input-values.d.ts +140 -0
- package/dist/form/input-values.js +206 -0
- package/dist/form/json-text.d.ts +11 -0
- package/dist/form/json-text.js +62 -37
- package/dist/form/save-pipeline.d.ts +6 -8
- package/dist/form/save-pipeline.js +91 -82
- package/dist/form/set-form-values.d.ts +6 -0
- package/dist/form/set-form-values.js +10 -0
- package/dist/form/source.js +97 -65
- package/dist/form/text-of.d.ts +2 -0
- package/dist/form/text-of.js +7 -0
- package/dist/form/validators.d.ts +58 -19
- package/dist/form/validators.js +97 -71
- package/dist/geo/bbox.d.ts +5 -4
- package/dist/geo/bbox.js +69 -48
- package/dist/geo/bounds.d.ts +14 -3
- package/dist/geo/bounds.js +98 -68
- package/dist/geo/constraints.js +88 -93
- package/dist/geo/coordinates.d.ts +10 -0
- package/dist/geo/coordinates.js +44 -23
- package/dist/geo/editor.d.ts +13 -13
- package/dist/geo/editor.js +176 -153
- package/dist/geo/geocoding.d.ts +4 -4
- package/dist/geo/geocoding.js +38 -41
- package/dist/geo/geojson.d.ts +12 -74
- package/dist/geo/geojson.js +52 -40
- package/dist/geo/geometry-math.d.ts +4 -4
- package/dist/geo/geometry-math.js +100 -93
- package/dist/geo/index.d.ts +9 -8
- package/dist/geo/map-layers.d.ts +42 -7
- package/dist/geo/map-layers.js +88 -62
- package/dist/geo/map-style.d.ts +12 -0
- package/dist/geo/map-style.js +43 -32
- package/dist/geo/messages.js +48 -45
- package/dist/geo/nominatim.js +88 -80
- package/dist/geo/osm-presets.d.ts +4 -3
- package/dist/geo/osm-presets.js +108 -86
- package/dist/geo/osm-tags.js +14 -12
- package/dist/geo/overpass.d.ts +14 -2
- package/dist/geo/overpass.js +83 -90
- package/dist/geo/shape-value.d.ts +9 -5
- package/dist/geo/shape-value.js +169 -146
- package/dist/geo/snap-to-roads.d.ts +3 -3
- package/dist/geo/snap-to-roads.js +55 -50
- package/dist/geo/throttle.js +36 -39
- package/dist/guards.d.ts +44 -0
- package/dist/guards.js +77 -0
- package/dist/i18n/default-messages.js +34 -29
- package/dist/i18n/english-messages.d.ts +172 -0
- package/dist/i18n/english-messages.js +359 -189
- package/dist/i18n/i18n.d.ts +2 -2
- package/dist/i18n/i18n.js +47 -60
- package/dist/i18n/inflection.d.ts +34 -0
- package/dist/i18n/inflection.js +82 -0
- package/dist/i18n/messages.d.ts +10 -2
- package/dist/i18n/messages.js +17 -4
- package/dist/i18n/missing-keys.d.ts +4 -0
- package/dist/i18n/missing-keys.js +70 -62
- package/dist/i18n/translatable.d.ts +16 -1
- package/dist/i18n/translatable.js +40 -47
- package/dist/index.d.ts +87 -39
- package/dist/index.js +54 -301
- package/dist/json/deep-equal.d.ts +8 -0
- package/dist/json/deep-equal.js +24 -0
- package/dist/json/strip-json-comments.js +38 -42
- package/dist/noop.d.ts +2 -0
- package/dist/noop.js +4 -0
- package/dist/notification/error-message.d.ts +2 -0
- package/dist/notification/error-message.js +10 -0
- package/dist/notification/notification-store.d.ts +3 -2
- package/dist/notification/notification-store.js +41 -45
- package/dist/onboarding-tour/placement.d.ts +2 -0
- package/dist/onboarding-tour/placement.js +65 -78
- package/dist/onboarding-tour/tour-controller.js +46 -54
- package/dist/realtime/add-events-for-mutations.js +75 -81
- package/dist/realtime/announce-lock.js +16 -13
- package/dist/realtime/broadcast-channel-transport.js +65 -59
- package/dist/realtime/copy-members.js +22 -14
- package/dist/realtime/in-memory-lock-provider.js +40 -48
- package/dist/realtime/live.js +95 -101
- package/dist/realtime/lock-options.js +16 -16
- package/dist/realtime/lock-session.js +91 -78
- package/dist/realtime/memory-transport.js +25 -25
- package/dist/realtime/presence.js +120 -122
- package/dist/realtime/realtime-data-provider.d.ts +10 -0
- package/dist/realtime/realtime-data-provider.js +45 -42
- package/dist/realtime/reconnect-backoff.js +17 -0
- package/dist/realtime/sse-transport.d.ts +31 -0
- package/dist/realtime/sse-transport.js +235 -0
- package/dist/realtime/status-store.js +23 -28
- package/dist/realtime/topic-hub.js +62 -71
- package/dist/realtime/topics.js +10 -12
- package/dist/realtime/types.js +10 -12
- package/dist/realtime/unread-count.js +21 -21
- package/dist/realtime/websocket-transport.d.ts +32 -0
- package/dist/realtime/websocket-transport.js +306 -0
- package/dist/resource/describe-resource.d.ts +2 -0
- package/dist/resource/describe-resource.js +247 -219
- package/dist/resource/get-at-path.js +29 -14
- package/dist/resource/identifier.d.ts +18 -0
- package/dist/resource/identifier.js +27 -0
- package/dist/resource/record.d.ts +4 -0
- package/dist/resource/record.js +10 -0
- package/dist/resource/register.d.ts +7 -0
- package/dist/resource/registry-store.d.ts +45 -15
- package/dist/resource/registry-store.js +67 -60
- package/dist/resource/registry.d.ts +10 -0
- package/dist/resource/registry.js +8 -4
- package/dist/resource/source-path.d.ts +23 -2
- package/dist/rich-text/rich-text-extras.d.ts +134 -0
- package/dist/rich-text/rich-text-extras.js +181 -0
- package/dist/rich-text/rich-text-image.d.ts +124 -0
- package/dist/rich-text/rich-text-image.js +163 -0
- package/dist/rich-text/rich-text.d.ts +6 -0
- package/dist/rich-text/rich-text.js +125 -88
- package/dist/router/location.d.ts +24 -4
- package/dist/router/location.js +43 -18
- package/dist/router/match.js +47 -39
- package/dist/router/paths.js +40 -34
- package/dist/router/record-from-location.d.ts +1 -1
- package/dist/router/record-from-location.js +25 -17
- package/dist/store/adapters.js +51 -55
- package/dist/store/micro-store.js +57 -59
- package/dist/store/shallow-equal.d.ts +12 -0
- package/dist/store/shallow-equal.js +20 -0
- package/dist/store/store.js +54 -57
- package/dist/ui-defaults.d.ts +15 -0
- package/dist/ui-defaults.js +17 -0
- package/package.json +13 -11
|
@@ -16,6 +16,12 @@ export interface CreateAssistantSessionOptions {
|
|
|
16
16
|
export interface AssistantSession extends MicroStore<AssistantSessionState> {
|
|
17
17
|
/** Resolves when the turn, with its tool rounds, ends. */
|
|
18
18
|
send(text: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* After an error, runs the last user message again: whatever the failed
|
|
21
|
+
* turn added after it is dropped and no second user message is added.
|
|
22
|
+
* Does nothing unless the status is `error`.
|
|
23
|
+
*/
|
|
24
|
+
retry(): Promise<void>;
|
|
19
25
|
stop(): void;
|
|
20
26
|
reset(): void;
|
|
21
27
|
}
|
|
@@ -1,185 +1,208 @@
|
|
|
1
1
|
import { createMicroStore } from "../store/micro-store.js";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
// src/assistant/assistant-session.ts
|
|
3
|
+
var toError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
4
|
+
var issuesText = (issues) => issues.map((issue) => issue.message).join("; ");
|
|
5
|
+
/** Resolves with `undefined` when the signal aborts before the promise settles. */
|
|
4
6
|
function raceAbort(promise, signal) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const onAbort = () => resolve(void 0);
|
|
9
|
+
if (signal.aborted) return onAbort();
|
|
10
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
11
|
+
promise.then(resolve, reject).finally(() => {
|
|
12
|
+
signal.removeEventListener("abort", onAbort);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
13
15
|
}
|
|
14
|
-
function createAssistantSession({
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
16
|
+
function createAssistantSession({ transport, tools, maxToolRounds = 5, confirmTool }) {
|
|
17
|
+
const store = createMicroStore({
|
|
18
|
+
messages: [],
|
|
19
|
+
status: "idle",
|
|
20
|
+
error: null
|
|
21
|
+
});
|
|
22
|
+
const declarations = Object.fromEntries(Object.entries(tools).map(([name, { description, parameters }]) => [name, {
|
|
23
|
+
description,
|
|
24
|
+
parameters
|
|
25
|
+
}]));
|
|
26
|
+
let active = null;
|
|
27
|
+
let destroyed = false;
|
|
28
|
+
store.onDestroy(() => {
|
|
29
|
+
destroyed = true;
|
|
30
|
+
active?.abort();
|
|
31
|
+
active = null;
|
|
32
|
+
});
|
|
33
|
+
async function runTool(call, signal) {
|
|
34
|
+
const base = {
|
|
35
|
+
role: "tool",
|
|
36
|
+
id: call.id,
|
|
37
|
+
toolName: call.toolName
|
|
38
|
+
};
|
|
39
|
+
const definition = Object.hasOwn(tools, call.toolName) ? tools[call.toolName] : void 0;
|
|
40
|
+
if (!definition) return {
|
|
41
|
+
...base,
|
|
42
|
+
error: `Unknown tool: ${call.toolName}`
|
|
43
|
+
};
|
|
44
|
+
const stopped = {
|
|
45
|
+
...base,
|
|
46
|
+
error: "Stopped"
|
|
47
|
+
};
|
|
48
|
+
try {
|
|
49
|
+
let args = call.args;
|
|
50
|
+
if (definition.schema) {
|
|
51
|
+
const outcome = await definition.schema["~standard"].validate(args);
|
|
52
|
+
if (signal.aborted) return stopped;
|
|
53
|
+
if (outcome.issues) return {
|
|
54
|
+
...base,
|
|
55
|
+
error: `Invalid arguments: ${issuesText(outcome.issues)}`
|
|
56
|
+
};
|
|
57
|
+
args = outcome.value;
|
|
58
|
+
}
|
|
59
|
+
if (definition.confirm) {
|
|
60
|
+
const answer = await confirmTool?.(call);
|
|
61
|
+
if (signal.aborted) return stopped;
|
|
62
|
+
if (!answer) return {
|
|
63
|
+
...base,
|
|
64
|
+
error: "The user declined to run this tool"
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
...base,
|
|
69
|
+
result: await definition.handler(args)
|
|
70
|
+
};
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return {
|
|
73
|
+
...base,
|
|
74
|
+
error: toError(error).message
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function run(controller) {
|
|
79
|
+
const { signal } = controller;
|
|
80
|
+
const update = (patch) => {
|
|
81
|
+
if (!signal.aborted) store.setState(patch);
|
|
82
|
+
};
|
|
83
|
+
for (let round = 0;; round++) {
|
|
84
|
+
let content = "";
|
|
85
|
+
let index = -1;
|
|
86
|
+
const calls = [];
|
|
87
|
+
let iterator;
|
|
88
|
+
try {
|
|
89
|
+
iterator = transport.send(store.getSnapshot().messages, declarations, { signal })[Symbol.asyncIterator]();
|
|
90
|
+
for (;;) {
|
|
91
|
+
const step = await raceAbort(iterator.next(), signal);
|
|
92
|
+
if (!step || step.done || signal.aborted) break;
|
|
93
|
+
const chunk = step.value;
|
|
94
|
+
if (chunk.type === "done") break;
|
|
95
|
+
if (chunk.type === "tool-call") {
|
|
96
|
+
const { id, toolName, args } = chunk;
|
|
97
|
+
calls.push({
|
|
98
|
+
id,
|
|
99
|
+
toolName,
|
|
100
|
+
args
|
|
101
|
+
});
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
content += chunk.delta;
|
|
105
|
+
const text = content;
|
|
106
|
+
if (index < 0) {
|
|
107
|
+
index = store.getSnapshot().messages.length;
|
|
108
|
+
update((s) => ({ messages: [...s.messages, {
|
|
109
|
+
role: "assistant",
|
|
110
|
+
content: text
|
|
111
|
+
}] }));
|
|
112
|
+
} else update((s) => ({ messages: s.messages.map((m, i) => i === index ? {
|
|
113
|
+
role: "assistant",
|
|
114
|
+
content: text
|
|
115
|
+
} : m) }));
|
|
116
|
+
}
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (!signal.aborted) update(() => ({
|
|
119
|
+
status: "error",
|
|
120
|
+
error: toError(error)
|
|
121
|
+
}));
|
|
122
|
+
return;
|
|
123
|
+
} finally {
|
|
124
|
+
iterator?.return?.().catch(() => {});
|
|
125
|
+
}
|
|
126
|
+
if (signal.aborted) return;
|
|
127
|
+
if (calls.length === 0) break;
|
|
128
|
+
if (round >= maxToolRounds) {
|
|
129
|
+
update(() => ({
|
|
130
|
+
status: "error",
|
|
131
|
+
error: /* @__PURE__ */ new Error(`The assistant kept calling tools after ${maxToolRounds} rounds`)
|
|
132
|
+
}));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const results = [];
|
|
136
|
+
for (const call of calls) {
|
|
137
|
+
const result = await raceAbort(runTool(call, signal), signal);
|
|
138
|
+
if (!result) return;
|
|
139
|
+
results.push(result);
|
|
140
|
+
if (signal.aborted) return;
|
|
141
|
+
}
|
|
142
|
+
const assistant = {
|
|
143
|
+
role: "assistant",
|
|
144
|
+
content,
|
|
145
|
+
toolCalls: calls
|
|
146
|
+
};
|
|
147
|
+
update((s) => ({ messages: index < 0 ? [
|
|
148
|
+
...s.messages,
|
|
149
|
+
assistant,
|
|
150
|
+
...results
|
|
151
|
+
] : [...s.messages.map((m, i) => i === index ? assistant : m), ...results] }));
|
|
152
|
+
}
|
|
153
|
+
update(() => ({ status: "idle" }));
|
|
154
|
+
}
|
|
155
|
+
async function start(controller) {
|
|
156
|
+
active = controller;
|
|
157
|
+
try {
|
|
158
|
+
await run(controller);
|
|
159
|
+
} finally {
|
|
160
|
+
if (active === controller) active = null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
...store,
|
|
165
|
+
async send(text) {
|
|
166
|
+
if (destroyed) return;
|
|
167
|
+
if (!text.trim() || store.getSnapshot().status === "streaming") return;
|
|
168
|
+
store.setState((s) => ({
|
|
169
|
+
messages: [...s.messages, {
|
|
170
|
+
role: "user",
|
|
171
|
+
content: text
|
|
172
|
+
}],
|
|
173
|
+
status: "streaming",
|
|
174
|
+
error: null
|
|
175
|
+
}));
|
|
176
|
+
await start(new AbortController());
|
|
177
|
+
},
|
|
178
|
+
async retry() {
|
|
179
|
+
if (destroyed || store.getSnapshot().status !== "error") return;
|
|
180
|
+
const { messages } = store.getSnapshot();
|
|
181
|
+
let last = messages.length - 1;
|
|
182
|
+
while (last >= 0 && messages[last]?.role !== "user") last--;
|
|
183
|
+
if (last < 0) return;
|
|
184
|
+
store.setState({
|
|
185
|
+
messages: messages.slice(0, last + 1),
|
|
186
|
+
status: "streaming",
|
|
187
|
+
error: null
|
|
188
|
+
});
|
|
189
|
+
await start(new AbortController());
|
|
190
|
+
},
|
|
191
|
+
stop() {
|
|
192
|
+
if (!active) return;
|
|
193
|
+
active.abort();
|
|
194
|
+
active = null;
|
|
195
|
+
store.setState({ status: "idle" });
|
|
196
|
+
},
|
|
197
|
+
reset() {
|
|
198
|
+
active?.abort();
|
|
199
|
+
active = null;
|
|
200
|
+
store.setState({
|
|
201
|
+
messages: [],
|
|
202
|
+
status: "idle",
|
|
203
|
+
error: null
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
};
|
|
182
207
|
}
|
|
183
|
-
export {
|
|
184
|
-
createAssistantSession
|
|
185
|
-
};
|
|
208
|
+
export { createAssistantSession };
|
|
@@ -1,31 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
// src/assistant/echo-transport.ts
|
|
2
|
+
var wait = (ms, signal) => new Promise((resolve) => {
|
|
3
|
+
const timer = setTimeout(done, ms);
|
|
4
|
+
function done() {
|
|
5
|
+
clearTimeout(timer);
|
|
6
|
+
signal.removeEventListener("abort", done);
|
|
7
|
+
resolve();
|
|
8
|
+
}
|
|
9
|
+
signal.addEventListener("abort", done, { once: true });
|
|
9
10
|
});
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
};
|
|
11
|
+
/** Replies `Echo: <last user text>` one character at a time, with no model behind it. */
|
|
12
|
+
function echoAssistantTransport({ delayMs = 0 } = {}) {
|
|
13
|
+
return { async *send(messages, _tools, { signal }) {
|
|
14
|
+
let said = "";
|
|
15
|
+
for (const message of messages) if (message.role === "user") said = message.content;
|
|
16
|
+
const reply = `Echo: ${said}`;
|
|
17
|
+
for (const delta of reply) {
|
|
18
|
+
if (delayMs > 0) await wait(delayMs, signal);
|
|
19
|
+
if (signal.aborted) return;
|
|
20
|
+
yield {
|
|
21
|
+
type: "text",
|
|
22
|
+
delta
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
yield { type: "done" };
|
|
26
|
+
} };
|
|
28
27
|
}
|
|
29
|
-
export {
|
|
30
|
-
echoAssistantTransport
|
|
31
|
-
};
|
|
28
|
+
export { echoAssistantTransport };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AssistantTransport } from "./types.js";
|
|
2
|
+
export interface HttpAssistantTransportOptions {
|
|
3
|
+
url: string;
|
|
4
|
+
/** Resolved for each request so tokens can change between turns. */
|
|
5
|
+
headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
|
6
|
+
credentials?: RequestCredentials;
|
|
7
|
+
fetch?: typeof globalThis.fetch;
|
|
8
|
+
}
|
|
9
|
+
/** Posts a conversation to an app endpoint that replies with NDJSON AssistantChunks. */
|
|
10
|
+
export declare function httpAssistantTransport(options: HttpAssistantTransportOptions): AssistantTransport;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { HttpError } from "../data/http-error.js";
|
|
2
|
+
import { isJsonObject, isRecord } from "../guards.js";
|
|
3
|
+
// src/assistant/http-transport.ts
|
|
4
|
+
function parseChunk(line, lineNumber) {
|
|
5
|
+
const invalid = () => /* @__PURE__ */ new Error(`Invalid assistant chunk at line ${lineNumber}`);
|
|
6
|
+
let chunk;
|
|
7
|
+
try {
|
|
8
|
+
chunk = JSON.parse(line);
|
|
9
|
+
} catch {
|
|
10
|
+
throw invalid();
|
|
11
|
+
}
|
|
12
|
+
if (isRecord(chunk)) switch (chunk.type) {
|
|
13
|
+
case "text":
|
|
14
|
+
if (typeof chunk.delta === "string") return {
|
|
15
|
+
type: "text",
|
|
16
|
+
delta: chunk.delta
|
|
17
|
+
};
|
|
18
|
+
break;
|
|
19
|
+
case "tool-call":
|
|
20
|
+
if (typeof chunk.id === "string" && typeof chunk.toolName === "string" && isJsonObject(chunk.args)) return {
|
|
21
|
+
type: "tool-call",
|
|
22
|
+
id: chunk.id,
|
|
23
|
+
toolName: chunk.toolName,
|
|
24
|
+
args: chunk.args
|
|
25
|
+
};
|
|
26
|
+
break;
|
|
27
|
+
case "done": return { type: "done" };
|
|
28
|
+
}
|
|
29
|
+
throw invalid();
|
|
30
|
+
}
|
|
31
|
+
/** Posts a conversation to an app endpoint that replies with NDJSON AssistantChunks. */
|
|
32
|
+
function httpAssistantTransport(options) {
|
|
33
|
+
const doFetch = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
34
|
+
return { async *send(messages, tools, { signal }) {
|
|
35
|
+
try {
|
|
36
|
+
if (signal.aborted) return;
|
|
37
|
+
const headers = new Headers(typeof options.headers === "function" ? await options.headers() : options.headers);
|
|
38
|
+
if (signal.aborted) return;
|
|
39
|
+
headers.set("Content-Type", "application/json");
|
|
40
|
+
const response = await doFetch(options.url, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers,
|
|
43
|
+
credentials: options.credentials,
|
|
44
|
+
body: JSON.stringify({
|
|
45
|
+
messages,
|
|
46
|
+
tools
|
|
47
|
+
}),
|
|
48
|
+
signal
|
|
49
|
+
});
|
|
50
|
+
if (!response.ok) throw new HttpError(`Assistant request failed (HTTP ${response.status})`, response.status, await response.text());
|
|
51
|
+
const reader = response.body?.getReader();
|
|
52
|
+
if (reader) {
|
|
53
|
+
const decoder = new TextDecoder();
|
|
54
|
+
let pending = "";
|
|
55
|
+
let lineNumber = 0;
|
|
56
|
+
let released = false;
|
|
57
|
+
const release = () => {
|
|
58
|
+
if (released) return;
|
|
59
|
+
released = true;
|
|
60
|
+
reader.cancel().catch(() => {});
|
|
61
|
+
reader.releaseLock();
|
|
62
|
+
};
|
|
63
|
+
signal.addEventListener("abort", release, { once: true });
|
|
64
|
+
try {
|
|
65
|
+
for (;;) {
|
|
66
|
+
if (signal.aborted) return;
|
|
67
|
+
const step = await reader.read();
|
|
68
|
+
if (signal.aborted) return;
|
|
69
|
+
pending += decoder.decode(step.value, { stream: !step.done });
|
|
70
|
+
if (step.done) pending += "\n";
|
|
71
|
+
let end = pending.indexOf("\n");
|
|
72
|
+
while (end >= 0) {
|
|
73
|
+
if (signal.aborted) return;
|
|
74
|
+
lineNumber++;
|
|
75
|
+
const line = pending.slice(0, end).trim();
|
|
76
|
+
pending = pending.slice(end + 1);
|
|
77
|
+
if (line) {
|
|
78
|
+
const chunk = parseChunk(line, lineNumber);
|
|
79
|
+
yield chunk;
|
|
80
|
+
if (chunk.type === "done") return;
|
|
81
|
+
}
|
|
82
|
+
end = pending.indexOf("\n");
|
|
83
|
+
}
|
|
84
|
+
if (step.done) break;
|
|
85
|
+
}
|
|
86
|
+
} finally {
|
|
87
|
+
signal.removeEventListener("abort", release);
|
|
88
|
+
release();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (signal.aborted) return;
|
|
92
|
+
yield { type: "done" };
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (!signal.aborted) throw error;
|
|
95
|
+
}
|
|
96
|
+
} };
|
|
97
|
+
}
|
|
98
|
+
export { httpAssistantTransport };
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from "@tanstack/form-core";
|
|
2
|
-
|
|
3
|
-
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
4
|
-
[key: string]: JsonValue;
|
|
5
|
-
};
|
|
6
|
-
export type JsonObject = {
|
|
7
|
-
[key: string]: JsonValue;
|
|
8
|
-
};
|
|
2
|
+
import type { JsonObject, JsonValue } from "../guards.js";
|
|
9
3
|
/** A tool call the model asked for. `id` ties the result back to it. */
|
|
10
4
|
export interface AssistantToolCall {
|
|
11
5
|
id: string;
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import type { ResourceRecord } from "../resource/record.js";
|
|
1
2
|
import type { CanAccessParams } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* One grant. `record` predicate (when present) must pass against a provided
|
|
5
|
+
* record, and reads it as `TRecord` — the same record shape the check is given.
|
|
6
|
+
*/
|
|
7
|
+
export interface Permission<TRecord extends ResourceRecord = ResourceRecord> {
|
|
4
8
|
action: string | string[];
|
|
5
9
|
resource: string;
|
|
6
|
-
record?: (record:
|
|
10
|
+
record?: (record: TRecord) => boolean;
|
|
7
11
|
}
|
|
8
|
-
/**
|
|
9
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Deny-by-default permission matcher (OR across permissions). `TRecord` is fixed
|
|
14
|
+
* by the permissions and the params together, so a grant's predicate and the
|
|
15
|
+
* record it reads are the same type.
|
|
16
|
+
*/
|
|
17
|
+
export declare function canAccessWithPermissions<TRecord extends ResourceRecord = ResourceRecord>(permissions: Permission<TRecord>[], params: CanAccessParams<TRecord>): boolean;
|