@nyte-ai/sdk 0.0.0-stage → 0.0.18
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/LICENSE +21 -0
- package/THIRD-PARTY-NOTICES.md +800 -0
- package/dist/chunks/capability-2q3s96kg.js +57 -0
- package/dist/chunks/capability-2wk9ktc5.js +161 -0
- package/dist/chunks/capability-3qe1hz8t.js +78 -0
- package/dist/chunks/capability-591c8vr1.js +134 -0
- package/dist/chunks/capability-8hmez9nw.js +199 -0
- package/dist/chunks/capability-9747w1b1.js +55 -0
- package/dist/chunks/capability-artgq59v.js +232 -0
- package/dist/chunks/capability-b52hty54.js +17 -0
- package/dist/chunks/capability-cdz2rz6h.js +208 -0
- package/dist/chunks/capability-esdwn315.js +26 -0
- package/dist/chunks/capability-mr5m2wn2.js +6 -0
- package/dist/chunks/capability-nh422cp0.js +35 -0
- package/dist/chunks/capability-y1amted3.js +230 -0
- package/dist/src/capability.d.ts +2 -0
- package/dist/src/capability.js +6 -0
- package/dist/src/client.d.ts +14 -0
- package/dist/src/client.js +14 -0
- package/dist/src/connect.d.ts +2 -0
- package/dist/src/connect.js +15 -0
- package/dist/src/history.d.ts +14 -0
- package/dist/src/history.js +7 -0
- package/dist/src/index.client.d.ts +10 -0
- package/dist/src/index.client.js +57 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.js +58 -0
- package/dist/src/index.web.d.ts +8 -0
- package/dist/src/index.web.js +63 -0
- package/dist/src/journal.d.ts +15 -0
- package/dist/src/journal.js +9 -0
- package/dist/src/login.d.ts +8 -0
- package/dist/src/login.js +6 -0
- package/dist/src/paint-spans.d.ts +11 -0
- package/dist/src/paint-spans.js +6 -0
- package/dist/src/part.d.ts +4 -0
- package/dist/src/part.js +6 -0
- package/dist/src/receipts.d.ts +9 -0
- package/dist/src/receipts.js +16 -0
- package/dist/src/rows.d.ts +37 -0
- package/dist/src/rows.js +12 -0
- package/dist/src/surface.d.ts +12 -0
- package/dist/src/surface.js +39 -0
- package/dist/src/watch.d.ts +30 -0
- package/dist/src/watch.js +14 -0
- package/dist/src/workspace.d.ts +4 -0
- package/dist/src/workspace.js +9 -0
- package/package.json +59 -3
- package/README.md +0 -3
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// src/rows.ts
|
|
2
|
+
import { SdkError } from "@nyte-ai/schema";
|
|
3
|
+
import { closable, dev } from "@nyte-ai/core";
|
|
4
|
+
import { decodeOutput, encodeInput } from "@nyte-ai/protocol";
|
|
5
|
+
var DONE = { done: true, value: undefined };
|
|
6
|
+
var FIRST_DELAY_MS = 50;
|
|
7
|
+
var BASE_DELAY_MS = 250;
|
|
8
|
+
var MAX_DELAY_MS = 1e4;
|
|
9
|
+
function createLink2() {
|
|
10
|
+
let state = { kind: "connected" };
|
|
11
|
+
const listeners = new Set;
|
|
12
|
+
const controller = new AbortController;
|
|
13
|
+
const publish = (next) => {
|
|
14
|
+
state = next;
|
|
15
|
+
for (const listener of listeners)
|
|
16
|
+
listener(next);
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
current: () => state,
|
|
20
|
+
lost() {
|
|
21
|
+
if (state.kind === "closed")
|
|
22
|
+
return;
|
|
23
|
+
publish(state.kind === "reconnecting" ? { ...state, attempts: state.attempts + 1 } : { kind: "reconnecting", since: Date.now(), attempts: 1 });
|
|
24
|
+
},
|
|
25
|
+
restored() {
|
|
26
|
+
if (state.kind === "reconnecting")
|
|
27
|
+
publish({ kind: "connected" });
|
|
28
|
+
},
|
|
29
|
+
close(reason) {
|
|
30
|
+
if (state.kind === "closed")
|
|
31
|
+
return;
|
|
32
|
+
dev("sdk", "link closed", { reason });
|
|
33
|
+
publish({ kind: "closed", reason });
|
|
34
|
+
controller.abort(new SdkError("unavailable", "The connection is closed."));
|
|
35
|
+
},
|
|
36
|
+
subscribe(listener) {
|
|
37
|
+
listeners.add(listener);
|
|
38
|
+
return () => {
|
|
39
|
+
listeners.delete(listener);
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
signal: controller.signal
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function createRows2(transport, link) {
|
|
46
|
+
const request = async (send, signal) => {
|
|
47
|
+
link.signal.throwIfAborted();
|
|
48
|
+
try {
|
|
49
|
+
const answer = await send(signal === undefined ? link.signal : AbortSignal.any([link.signal, signal]));
|
|
50
|
+
link.restored();
|
|
51
|
+
return answer;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
if (hostGone(transport, error))
|
|
54
|
+
link.close("host-gone");
|
|
55
|
+
link.signal.throwIfAborted();
|
|
56
|
+
if (linkLost(error))
|
|
57
|
+
link.lost();
|
|
58
|
+
if (error instanceof SdkError && error.code === "unauthenticated")
|
|
59
|
+
link.close("revoked");
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const call = async (name, input, options) => decodeOutput(name, await request((signal) => transport.invoke(name, encodeInput(name, input), { signal }), options?.signal));
|
|
64
|
+
return {
|
|
65
|
+
link,
|
|
66
|
+
operations: () => transport.operations(),
|
|
67
|
+
call,
|
|
68
|
+
async wait(name, input, options) {
|
|
69
|
+
for (let attempts = 1;; attempts += 1) {
|
|
70
|
+
try {
|
|
71
|
+
return await call(name, input, options);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if (!linkLost(error) || link.signal.aborted || options?.signal?.aborted === true)
|
|
74
|
+
throw error;
|
|
75
|
+
dev("sdk", "wait retrying", { name, attempts });
|
|
76
|
+
await backoff2(link, retryDelay2(attempts), options?.signal === undefined ? link.signal : AbortSignal.any([link.signal, options.signal]));
|
|
77
|
+
options?.signal?.throwIfAborted();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
async upload(name, input, body) {
|
|
82
|
+
return decodeOutput(name, await request((signal) => transport.upload(name, encodeInput(name, input), body, { signal }), undefined));
|
|
83
|
+
},
|
|
84
|
+
bytes: (name, input, options) => request((signal) => transport.bytes(name, encodeInput(name, input), { signal }), options?.signal),
|
|
85
|
+
frames: (name, input) => through(transport.frames(name, encodeInput(name, input)), (frame) => decoded(name, frame), link.signal),
|
|
86
|
+
watch: (name, input, opened) => resumable(transport, link, name, encodeInput(name, input), opened),
|
|
87
|
+
output: (input) => through(transport.output(encodeInput("job.output", input)), (frame) => frame.kind === "bytes" ? { value: frame } : decoded("job.output", frame), link.signal)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function resumable(transport, link, name, input, opened) {
|
|
91
|
+
return closable(() => {
|
|
92
|
+
const stop = new AbortController;
|
|
93
|
+
const signal = AbortSignal.any([stop.signal, link.signal]);
|
|
94
|
+
let frames = opened ?? null;
|
|
95
|
+
let attempts = 0;
|
|
96
|
+
let reopened = false;
|
|
97
|
+
const release = () => {
|
|
98
|
+
frames?.return?.();
|
|
99
|
+
};
|
|
100
|
+
signal.addEventListener("abort", release, { once: true });
|
|
101
|
+
return {
|
|
102
|
+
async pull() {
|
|
103
|
+
for (;; ) {
|
|
104
|
+
if (signal.aborted)
|
|
105
|
+
return DONE;
|
|
106
|
+
const current = frames ?? transport.frames(name, input)[Symbol.asyncIterator]();
|
|
107
|
+
frames = current;
|
|
108
|
+
let next = DONE;
|
|
109
|
+
try {
|
|
110
|
+
next = await current.next();
|
|
111
|
+
} catch (error) {
|
|
112
|
+
if (hostGone(transport, error)) {
|
|
113
|
+
link.close("host-gone");
|
|
114
|
+
return DONE;
|
|
115
|
+
}
|
|
116
|
+
if (error instanceof SdkError && error.code === "unauthenticated") {
|
|
117
|
+
link.close("revoked");
|
|
118
|
+
return DONE;
|
|
119
|
+
}
|
|
120
|
+
if (!linkLost(error))
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
if (next.done !== true) {
|
|
124
|
+
if (attempts > 0) {
|
|
125
|
+
dev("sdk", "watch resumed", { name, attempts });
|
|
126
|
+
link.restored();
|
|
127
|
+
}
|
|
128
|
+
attempts = 0;
|
|
129
|
+
const value = decoded(name, next.value);
|
|
130
|
+
if (value !== null) {
|
|
131
|
+
reopened = false;
|
|
132
|
+
return { done: false, value: value.value };
|
|
133
|
+
}
|
|
134
|
+
if (reopened)
|
|
135
|
+
throw new SdkError("invalid", `The host sends ${name} frames this client cannot read.`);
|
|
136
|
+
reopened = true;
|
|
137
|
+
frames = null;
|
|
138
|
+
current.return?.();
|
|
139
|
+
dev("sdk", "watch reopened", { name });
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
frames = null;
|
|
143
|
+
if (signal.aborted)
|
|
144
|
+
return DONE;
|
|
145
|
+
attempts += 1;
|
|
146
|
+
dev("sdk", "watch reconnecting", { name, attempts });
|
|
147
|
+
link.lost();
|
|
148
|
+
await backoff2(link, retryDelay2(attempts), signal);
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
close() {
|
|
152
|
+
signal.removeEventListener("abort", release);
|
|
153
|
+
stop.abort();
|
|
154
|
+
release();
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function through(source, map, signal) {
|
|
160
|
+
return {
|
|
161
|
+
[Symbol.asyncIterator]() {
|
|
162
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
163
|
+
const stop = () => {
|
|
164
|
+
iterator.return?.();
|
|
165
|
+
};
|
|
166
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
167
|
+
return {
|
|
168
|
+
async next() {
|
|
169
|
+
for (;; ) {
|
|
170
|
+
if (signal.aborted)
|
|
171
|
+
return DONE;
|
|
172
|
+
const next = await iterator.next();
|
|
173
|
+
if (next.done === true) {
|
|
174
|
+
signal.removeEventListener("abort", stop);
|
|
175
|
+
return DONE;
|
|
176
|
+
}
|
|
177
|
+
const mapped = map(next.value);
|
|
178
|
+
if (mapped !== null)
|
|
179
|
+
return { done: false, value: mapped.value };
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
async return() {
|
|
183
|
+
signal.removeEventListener("abort", stop);
|
|
184
|
+
await iterator.return?.();
|
|
185
|
+
return DONE;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function decoded(name, data) {
|
|
192
|
+
try {
|
|
193
|
+
return { value: decodeOutput(name, data) };
|
|
194
|
+
} catch (error) {
|
|
195
|
+
if (!(error instanceof SdkError) || error.code !== "invalid")
|
|
196
|
+
throw error;
|
|
197
|
+
dev("sdk", "frame skipped", { name, message: error.message });
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function hostGone(transport, error) {
|
|
202
|
+
const pinned = transport.host();
|
|
203
|
+
return error instanceof SdkError && error.code === "stale" && pinned !== null && error.hostId !== null && error.hostId !== pinned;
|
|
204
|
+
}
|
|
205
|
+
function linkLost(error) {
|
|
206
|
+
return error instanceof SdkError && error.code === "unavailable";
|
|
207
|
+
}
|
|
208
|
+
function retryDelay2(attempts) {
|
|
209
|
+
return attempts <= 1 ? FIRST_DELAY_MS : Math.min(BASE_DELAY_MS * 2 ** (attempts - 2), MAX_DELAY_MS);
|
|
210
|
+
}
|
|
211
|
+
function backoff2(link, ms, signal) {
|
|
212
|
+
return new Promise((resolve) => {
|
|
213
|
+
if (signal.aborted) {
|
|
214
|
+
resolve();
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const done = () => {
|
|
218
|
+
clearTimeout(timer);
|
|
219
|
+
signal.removeEventListener("abort", done);
|
|
220
|
+
unsubscribe();
|
|
221
|
+
resolve();
|
|
222
|
+
};
|
|
223
|
+
const timer = setTimeout(done, ms);
|
|
224
|
+
signal.addEventListener("abort", done, { once: true });
|
|
225
|
+
const unsubscribe = link.subscribe((state) => {
|
|
226
|
+
if (state.kind === "connected")
|
|
227
|
+
done();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export { createLink2, createRows2, retryDelay2, backoff2 };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/surface.ts
|
|
2
|
+
import { dev as dev2, watchStore as watchStore2 } from "@nyte-ai/core";
|
|
3
|
+
import {
|
|
4
|
+
clearSpans as clearSpans2,
|
|
5
|
+
enableTracing as enableTracing2,
|
|
6
|
+
followTrace as followTrace2,
|
|
7
|
+
followedTrace as followedTrace2,
|
|
8
|
+
readSpans as readSpans2,
|
|
9
|
+
SPAN_NAMES as SPAN_NAMES2,
|
|
10
|
+
startSpan as startSpan2,
|
|
11
|
+
traced as traced2,
|
|
12
|
+
tracing as tracing2
|
|
13
|
+
} from "@nyte-ai/core";
|
|
14
|
+
import { SdkError as SdkError2 } from "@nyte-ai/schema";
|
|
15
|
+
import { operationsDigest as operationsDigest2 } from "@nyte-ai/protocol";
|
|
16
|
+
|
|
17
|
+
export { dev2, watchStore2, clearSpans2, enableTracing2, followTrace2, followedTrace2, readSpans2, SPAN_NAMES2, startSpan2, traced2, tracing2, SdkError2, operationsDigest2 };
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createHeadViews2,
|
|
3
|
+
watchHead2,
|
|
4
|
+
watchHost2,
|
|
5
|
+
withUnsent2
|
|
6
|
+
} from "./capability-8hmez9nw.js";
|
|
7
|
+
import {
|
|
8
|
+
createLink2,
|
|
9
|
+
createRows2
|
|
10
|
+
} from "./capability-artgq59v.js";
|
|
11
|
+
import {
|
|
12
|
+
journalLoop2
|
|
13
|
+
} from "./capability-2wk9ktc5.js";
|
|
14
|
+
import {
|
|
15
|
+
partHandle2
|
|
16
|
+
} from "./capability-9747w1b1.js";
|
|
17
|
+
import {
|
|
18
|
+
receiptHandle2,
|
|
19
|
+
sendReceipt2,
|
|
20
|
+
runHandle2,
|
|
21
|
+
moveOutcome2
|
|
22
|
+
} from "./capability-2q3s96kg.js";
|
|
23
|
+
import {
|
|
24
|
+
loginHandle2
|
|
25
|
+
} from "./capability-nh422cp0.js";
|
|
26
|
+
import {
|
|
27
|
+
workspaceHandle2
|
|
28
|
+
} from "./capability-y1amted3.js";
|
|
29
|
+
|
|
30
|
+
// src/client.ts
|
|
31
|
+
import { asId, isJson, SdkError } from "@nyte-ai/schema";
|
|
32
|
+
import { dev, followTrace, traced, watchStore } from "@nyte-ai/core";
|
|
33
|
+
var MAIN = asId("main");
|
|
34
|
+
function createClient2(transport, context) {
|
|
35
|
+
const link = createLink2();
|
|
36
|
+
const rows = createRows2(transport, link);
|
|
37
|
+
const bound = {
|
|
38
|
+
rows,
|
|
39
|
+
journal: journalLoop2(rows, context.journal),
|
|
40
|
+
views: createHeadViews2(rows)
|
|
41
|
+
};
|
|
42
|
+
bound.journal.replay(context.journaled);
|
|
43
|
+
let hostFrames = context.hostFrames;
|
|
44
|
+
link.signal.addEventListener("abort", () => void hostFrames?.return?.(), { once: true });
|
|
45
|
+
const close = async () => {
|
|
46
|
+
link.close("client");
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
hostId: context.hostId,
|
|
50
|
+
principal: context.principal,
|
|
51
|
+
credential: context.credential,
|
|
52
|
+
sessions: {
|
|
53
|
+
watch: (input) => rows.watch("sessions.watch", input ?? {}),
|
|
54
|
+
async start(input) {
|
|
55
|
+
const id = input.id ?? asId(crypto.randomUUID());
|
|
56
|
+
followTrace(id, id);
|
|
57
|
+
const started = await traced("sdk.send", id, { session: id }, () => rows.wait("sessions.start", { ...input, id }));
|
|
58
|
+
return {
|
|
59
|
+
session: sessionHandle(bound, started.session),
|
|
60
|
+
receipt: sendReceipt2(rows, started.session, started.receipt, started.message)
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
list: (input) => rows.call("sessions.list", input ?? {})
|
|
64
|
+
},
|
|
65
|
+
workspaces: {
|
|
66
|
+
list: () => rows.call("workspaces.list", {}),
|
|
67
|
+
inspect: (target) => rows.call("workspaces.inspect", { target }),
|
|
68
|
+
add: (target, options) => rows.call("workspaces.add", { target, options }),
|
|
69
|
+
forget: (id) => rows.call("workspaces.forget", { id })
|
|
70
|
+
},
|
|
71
|
+
session: (id) => sessionHandle(bound, id),
|
|
72
|
+
workspace: (id) => workspaceHandle2(rows, id),
|
|
73
|
+
watch: () => {
|
|
74
|
+
const opened = hostFrames;
|
|
75
|
+
hostFrames = undefined;
|
|
76
|
+
return watchHost2(rows, opened);
|
|
77
|
+
},
|
|
78
|
+
blob: (id) => rows.bytes("connection.blob", { id }),
|
|
79
|
+
models: {
|
|
80
|
+
list: () => rows.call("models.list", {}),
|
|
81
|
+
accounts: (provider) => rows.call("models.accounts", { provider }),
|
|
82
|
+
async selectAccount(provider, account) {
|
|
83
|
+
await rows.call("models.selectAccount", { provider, account });
|
|
84
|
+
},
|
|
85
|
+
usage: () => rows.call("models.usage", {}),
|
|
86
|
+
async refresh(provider) {
|
|
87
|
+
await rows.call("models.refresh", { provider });
|
|
88
|
+
},
|
|
89
|
+
setDefault: (ref) => rows.call("models.setDefault", { ref }),
|
|
90
|
+
verify: (provider) => rows.call("models.verify", { provider }),
|
|
91
|
+
login: (input) => loginHandle2(rows, async () => {
|
|
92
|
+
await rows.call("models.login", input);
|
|
93
|
+
return input.provider;
|
|
94
|
+
}, input.provider),
|
|
95
|
+
async logout(provider) {
|
|
96
|
+
await rows.call("models.logout", { provider });
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
settings: { apply: (id, value) => rows.call("settings.apply", { id, value }) },
|
|
100
|
+
github: {
|
|
101
|
+
account: () => rows.call("github.account", {}),
|
|
102
|
+
signIn: () => rows.call("github.signIn", {}),
|
|
103
|
+
signOut: () => rows.call("github.signOut", {})
|
|
104
|
+
},
|
|
105
|
+
plugins: {
|
|
106
|
+
replace: (plugins, scope) => rows.call("plugins.replace", { plugins: files(plugins), scope }),
|
|
107
|
+
check: (plugins) => rows.call("plugins.check", { plugins: files(plugins) })
|
|
108
|
+
},
|
|
109
|
+
principals: {
|
|
110
|
+
list: async () => (await rows.call("principals.list", {})).map((view) => ({
|
|
111
|
+
...view,
|
|
112
|
+
authority: new Set(view.authority)
|
|
113
|
+
})),
|
|
114
|
+
pair: (input) => rows.call("principals.pair", { authority: [...input.authority], label: input.label }),
|
|
115
|
+
async revoke(id) {
|
|
116
|
+
await rows.call("principals.revoke", { id });
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
close,
|
|
120
|
+
[Symbol.asyncDispose]: close
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function sessionHandle(bound, session) {
|
|
124
|
+
const { rows } = bound;
|
|
125
|
+
return {
|
|
126
|
+
...headHandle(bound, session, MAIN),
|
|
127
|
+
id: session,
|
|
128
|
+
head: (name) => headHandle(bound, session, name),
|
|
129
|
+
heads: {
|
|
130
|
+
create: (name, input) => rows.call("heads.create", { session, name, input }),
|
|
131
|
+
merge: (name, options) => rows.call("heads.merge", { session, name, options }),
|
|
132
|
+
remove: (name, options) => rows.call("heads.remove", { session, name, options })
|
|
133
|
+
},
|
|
134
|
+
run: (id) => runHandle2(rows, session, id),
|
|
135
|
+
receipt: (id) => receiptHandle2(rows, session, id, (outcome) => outcome),
|
|
136
|
+
info: () => rows.call("session.info", { session }),
|
|
137
|
+
update: (patch) => rows.call("session.update", { session, patch }),
|
|
138
|
+
remove: () => rows.call("session.remove", { session }),
|
|
139
|
+
stop: () => rows.call("session.stop", { session }),
|
|
140
|
+
command: (name, text) => rows.call("session.command", { session, name, text }),
|
|
141
|
+
completeCommand: (name, prefix) => rows.call("session.completeCommand", { session, name, prefix }),
|
|
142
|
+
parts: {
|
|
143
|
+
async create(kind, input) {
|
|
144
|
+
const { part } = await rows.call("parts.create", {
|
|
145
|
+
session,
|
|
146
|
+
kind: kind.kind,
|
|
147
|
+
input: { ...input, state: jsonState(input.state) }
|
|
148
|
+
});
|
|
149
|
+
return partHandle2(rows, session, part, kind);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
part: (id) => partHandle2(rows, session, id, null)
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function headHandle(bound, session, head) {
|
|
156
|
+
const { rows, journal } = bound;
|
|
157
|
+
return {
|
|
158
|
+
sessionId: session,
|
|
159
|
+
name: head,
|
|
160
|
+
async send(content, options) {
|
|
161
|
+
const { id, ...rest } = options ?? {};
|
|
162
|
+
const receipt = id ?? asId(crypto.randomUUID());
|
|
163
|
+
dev("sdk", "send", { session, head, receipt });
|
|
164
|
+
followTrace(session, receipt);
|
|
165
|
+
const sent = await traced("sdk.send", receipt, { session }, () => journal.send({
|
|
166
|
+
id: receipt,
|
|
167
|
+
session,
|
|
168
|
+
head,
|
|
169
|
+
content,
|
|
170
|
+
options: rest,
|
|
171
|
+
at: Date.now()
|
|
172
|
+
}));
|
|
173
|
+
return sendReceipt2(rows, session, sent.receipt, sent.message);
|
|
174
|
+
},
|
|
175
|
+
configure: (patch) => rows.call("head.configure", { session, head, patch }),
|
|
176
|
+
async view(options) {
|
|
177
|
+
const view = await rows.call("head.view", { session, head, options });
|
|
178
|
+
journal.landed(session, head, view);
|
|
179
|
+
const ids = new Set(view.messages.map((message) => message.id));
|
|
180
|
+
return withUnsent2(view, journal.unsent(session, head), (id) => ids.has(id));
|
|
181
|
+
},
|
|
182
|
+
watch: (options) => watchHead2(bound.views, journal, { session, head, options }),
|
|
183
|
+
...watchStore(() => watchHead2(bound.views, journal, { session, head })),
|
|
184
|
+
history: (input) => rows.call("head.history", { session, head, ...input }),
|
|
185
|
+
tree: () => rows.call("head.tree", { session, head }),
|
|
186
|
+
async move(position, options) {
|
|
187
|
+
const { receipt } = await rows.call("head.move", {
|
|
188
|
+
session,
|
|
189
|
+
head,
|
|
190
|
+
position,
|
|
191
|
+
options,
|
|
192
|
+
id: asId(crypto.randomUUID())
|
|
193
|
+
});
|
|
194
|
+
return receiptHandle2(rows, session, receipt, moveOutcome2);
|
|
195
|
+
},
|
|
196
|
+
compact: (input) => rows.call("head.compact", { session, head, ...input })
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function jsonState(state) {
|
|
200
|
+
if (isJson(state))
|
|
201
|
+
return state;
|
|
202
|
+
throw new SdkError("invalid", "A part's state must be JSON.");
|
|
203
|
+
}
|
|
204
|
+
function files(plugins) {
|
|
205
|
+
return plugins.map((plugin) => ({ path: plugin.path }));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export { createClient2 };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/paint-spans.ts
|
|
2
|
+
import { followedTrace, startSpan, tracing } from "@nyte-ai/core";
|
|
3
|
+
function tracePaints2(views, session, painted) {
|
|
4
|
+
return tracing.enabled ? timed(views, session, painted) : views;
|
|
5
|
+
}
|
|
6
|
+
async function* timed(views, session, painted) {
|
|
7
|
+
let shown = null;
|
|
8
|
+
for await (const view of views) {
|
|
9
|
+
const ids = new Set(view.messages.map((message) => message.id));
|
|
10
|
+
const followed = followedTrace(session);
|
|
11
|
+
for (const message of view.messages) {
|
|
12
|
+
if (shown === null ? message.id !== followed : shown.has(message.id))
|
|
13
|
+
continue;
|
|
14
|
+
const user = message.kind === "user";
|
|
15
|
+
const ended = startSpan("client.paint", user ? message.id : followed, {
|
|
16
|
+
session,
|
|
17
|
+
kind: user ? "user" : message.partKind
|
|
18
|
+
});
|
|
19
|
+
painted().then(() => ended());
|
|
20
|
+
}
|
|
21
|
+
shown = ids;
|
|
22
|
+
yield view;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { tracePaints2 };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/login.ts
|
|
2
|
+
import { SdkError } from "@nyte-ai/schema";
|
|
3
|
+
import { closable } from "@nyte-ai/core";
|
|
4
|
+
function loginHandle2(rows, begin, known) {
|
|
5
|
+
let started = null;
|
|
6
|
+
return {
|
|
7
|
+
steps: () => closable(() => {
|
|
8
|
+
let steps = null;
|
|
9
|
+
let closed = false;
|
|
10
|
+
return {
|
|
11
|
+
async pull() {
|
|
12
|
+
if (steps === null) {
|
|
13
|
+
const provider = await (started ??= begin());
|
|
14
|
+
if (closed)
|
|
15
|
+
return { done: true, value: undefined };
|
|
16
|
+
steps = rows.frames("login.steps", { provider })[Symbol.asyncIterator]();
|
|
17
|
+
}
|
|
18
|
+
return steps.next();
|
|
19
|
+
},
|
|
20
|
+
close() {
|
|
21
|
+
closed = true;
|
|
22
|
+
steps?.return?.();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}),
|
|
26
|
+
async answer(code) {
|
|
27
|
+
const provider = started === null ? known : await started;
|
|
28
|
+
if (provider === null)
|
|
29
|
+
throw new SdkError("invalid", "Read the login's steps before answering.");
|
|
30
|
+
await rows.call("login.answer", { provider, code });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { loginHandle2 };
|