@spredr/sdk 0.0.0-stage → 0.1.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/LICENSE +33 -0
- package/README.md +423 -2
- package/TRADEMARKS.md +18 -0
- package/dist/agent.d.ts +96 -0
- package/dist/caller.d.ts +30 -0
- package/dist/context.d.ts +108 -0
- package/dist/errors.d.ts +45 -0
- package/dist/http.d.ts +48 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +969 -0
- package/dist/owner.d.ts +162 -0
- package/dist/schema.d.ts +28 -0
- package/dist/sign.d.ts +26 -0
- package/dist/tag.d.ts +7 -0
- package/dist/tasks.d.ts +98 -0
- package/dist/types.d.ts +293 -0
- package/dist/usage.d.ts +3 -0
- package/package.json +51 -4
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { Client } from './http.js';
|
|
2
|
+
import type { Answer, Fact, Json, SessionFile, Step, Task } from './types.js';
|
|
3
|
+
export interface Delivery {
|
|
4
|
+
/** Whom ai addressed it to, inside what it signs: an agent refuses one addressed to another. Absent from an older ai. */
|
|
5
|
+
to?: {
|
|
6
|
+
agent: string;
|
|
7
|
+
};
|
|
8
|
+
task: {
|
|
9
|
+
id: string;
|
|
10
|
+
kind: string;
|
|
11
|
+
input: Json;
|
|
12
|
+
attempt: number;
|
|
13
|
+
by: Task['by'];
|
|
14
|
+
trial: boolean;
|
|
15
|
+
judges: string | null;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
tenant?: string;
|
|
18
|
+
thread?: string | null;
|
|
19
|
+
};
|
|
20
|
+
/** The last answer only: what an ai from before the journal sends. */
|
|
21
|
+
resume: (Answer & {
|
|
22
|
+
pause: string;
|
|
23
|
+
action: string;
|
|
24
|
+
question?: string;
|
|
25
|
+
data?: Json | null;
|
|
26
|
+
}) | null;
|
|
27
|
+
/** Every answer the task's questions got, in the order asked (free ones too). */
|
|
28
|
+
answers?: (Answer & {
|
|
29
|
+
pause: string;
|
|
30
|
+
action: string;
|
|
31
|
+
auto?: boolean;
|
|
32
|
+
question?: string;
|
|
33
|
+
data?: Json | null;
|
|
34
|
+
})[];
|
|
35
|
+
/** What each finished step gave back, in order: `key` is the step as the handler named it. */
|
|
36
|
+
memo?: {
|
|
37
|
+
key: string;
|
|
38
|
+
has: boolean;
|
|
39
|
+
value: Json;
|
|
40
|
+
}[];
|
|
41
|
+
lessons: {
|
|
42
|
+
version: number;
|
|
43
|
+
items: string[];
|
|
44
|
+
};
|
|
45
|
+
/** Its session's files, without their bytes: what an ai from before sessions' files does not send. */
|
|
46
|
+
files?: SessionFile[];
|
|
47
|
+
}
|
|
48
|
+
export interface Context {
|
|
49
|
+
task: Delivery['task'];
|
|
50
|
+
/** Whom it works for in this task (a user, an account, a team, a business): its memory, freedom, lessons and caps are that tenant's.
|
|
51
|
+
* "" when the asker named no one. */
|
|
52
|
+
tenant: string;
|
|
53
|
+
/** The conversation it belongs to (a customer, a ticket), when the asker named one. */
|
|
54
|
+
thread: string | null;
|
|
55
|
+
/** The live lessons this task carries: put them in the prompt. */
|
|
56
|
+
lessons: string[];
|
|
57
|
+
/** A trial replays an old task with new lessons: do nothing real. */
|
|
58
|
+
trial: boolean;
|
|
59
|
+
/** Asks before an action and returns the answer; the first time the task stops here and comes back with it. Asked
|
|
60
|
+
* again when the task runs again, it gives back the same answer without asking. */
|
|
61
|
+
ask(action: string, question: string, extra?: {
|
|
62
|
+
options?: string[];
|
|
63
|
+
data?: Json;
|
|
64
|
+
}): Promise<Answer>;
|
|
65
|
+
progress(data: Json): Promise<void>;
|
|
66
|
+
/** The next piece of its answer, for whoever watches the task live (the caller's stream()): sent in order, a few at a
|
|
67
|
+
* time. A view, never the outcome: what the task returns is its result, and the pieces go once it is done. */
|
|
68
|
+
stream(text: string): void;
|
|
69
|
+
/** Sends what stream() still holds: done for you before the task's result. */
|
|
70
|
+
flush(): Promise<void>;
|
|
71
|
+
/** Reports one step it took (a model call, a tool): its trace and its costs come from these. */
|
|
72
|
+
step(step: Step): Promise<void>;
|
|
73
|
+
/** Runs `work`, times it, and reports it as a step (failed when it throws). Tokens and cost from what it returns, if
|
|
74
|
+
* `usage` reads them. Done once per task: when the task runs again (after a question, a retry) it gives back what
|
|
75
|
+
* `work` gave the first time, as JSON, without running it. Put side effects here so they never happen twice. */
|
|
76
|
+
track<T>(kind: Step['kind'], name: string, work: () => Promise<T>, usage?: (value: T) => Pick<Step, 'model' | 'tokensIn' | 'tokensOut' | 'costUsd' | 'detail'>): Promise<T>;
|
|
77
|
+
/** A model call, timed and reported with its model and tokens read from the answer (Claude, OpenAI, the AI SDK):
|
|
78
|
+
* `await ctx.model(() => claude.messages.create({ … }))`. `name` defaults to the model. Done once per task, as track. */
|
|
79
|
+
model<T>(work: () => Promise<T>, name?: string): Promise<T>;
|
|
80
|
+
/** A task for later (a reminder, a follow-up), for the same tenant and thread. Done once per task, as track. */
|
|
81
|
+
later(kind: string, input: Json, at: Date | string, key?: string): Promise<void>;
|
|
82
|
+
/** Its session's files (the thread's, for its tenant): whatever its caller left for it to read, without their bytes. */
|
|
83
|
+
files: SessionFile[];
|
|
84
|
+
/** One of them, by id or by name, as its bytes and type: read inside this task, the way its code wants. */
|
|
85
|
+
file(idOrName: string): Promise<{
|
|
86
|
+
data: Uint8Array;
|
|
87
|
+
type: string;
|
|
88
|
+
name: string;
|
|
89
|
+
}>;
|
|
90
|
+
/** This tenant's memory (this task's): the agent's room is shared by all its tenants, each fact is one tenant's. */
|
|
91
|
+
memory: {
|
|
92
|
+
/** Done once per task, as track. The fact kept, or null when it was not (its room is full, or its tenant's share):
|
|
93
|
+
* the task goes on either way, and why is printed in its logs. */
|
|
94
|
+
remember(scope: string, text: string, extra?: {
|
|
95
|
+
key?: string;
|
|
96
|
+
data?: Json;
|
|
97
|
+
}): Promise<Fact | null>;
|
|
98
|
+
recall(options: {
|
|
99
|
+
scope?: string;
|
|
100
|
+
q?: string;
|
|
101
|
+
limit?: number;
|
|
102
|
+
}): Promise<Fact[]>;
|
|
103
|
+
forget(id: string): Promise<void>;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** Thrown inside ask() to stop a task that waits for an answer; the agent catches it. */
|
|
107
|
+
export declare const PAUSED: unique symbol;
|
|
108
|
+
export declare function contextFor(client: Client, delivery: Delivery): Context;
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Task } from './types.js';
|
|
2
|
+
export declare class SpredrError extends Error {
|
|
3
|
+
/** The HTTP status ai answered with; 0 when no answer came. */
|
|
4
|
+
readonly status: number;
|
|
5
|
+
/** ai's trace id for this request, to quote when you write to spredr. */
|
|
6
|
+
readonly trace: string;
|
|
7
|
+
constructor(status: number, message: string, trace?: string);
|
|
8
|
+
}
|
|
9
|
+
/** 400: what was sent is not right; the message says what. */
|
|
10
|
+
export declare class BadRequestError extends SpredrError {
|
|
11
|
+
}
|
|
12
|
+
/** 401: no token, a wrong one, or a signature ai does not believe. */
|
|
13
|
+
export declare class AuthenticationError extends SpredrError {
|
|
14
|
+
}
|
|
15
|
+
/** 403: allowed to ask, not this (a plan's limit, another owner's agent). */
|
|
16
|
+
export declare class PermissionDeniedError extends SpredrError {
|
|
17
|
+
}
|
|
18
|
+
/** 404: no such agent, task or question. */
|
|
19
|
+
export declare class NotFoundError extends SpredrError {
|
|
20
|
+
}
|
|
21
|
+
/** 409: it changed meanwhile (a name taken, a question already answered, an attempt that is over). */
|
|
22
|
+
export declare class ConflictError extends SpredrError {
|
|
23
|
+
}
|
|
24
|
+
/** 429: too many, or a cap reached (the month's tasks, the day's spend); `retryAfter` says when to come back. */
|
|
25
|
+
export declare class RateLimitError extends SpredrError {
|
|
26
|
+
/** Seconds ai asked to wait, when it said. */
|
|
27
|
+
readonly retryAfter: number | null;
|
|
28
|
+
constructor(status: number, message: string, trace?: string, retryAfter?: number | null);
|
|
29
|
+
}
|
|
30
|
+
/** 5xx: ai failed; retried already, as far as it is safe. */
|
|
31
|
+
export declare class InternalServerError extends SpredrError {
|
|
32
|
+
}
|
|
33
|
+
/** No answer: the network, a DNS name, ai unreachable. */
|
|
34
|
+
export declare class ConnectionError extends SpredrError {
|
|
35
|
+
}
|
|
36
|
+
/** No answer in time (timeoutMs). */
|
|
37
|
+
export declare class TimeoutError extends ConnectionError {
|
|
38
|
+
}
|
|
39
|
+
/** A task that ended without a result: failed, canceled, or paused for a question someone must answer. */
|
|
40
|
+
export declare class TaskError extends Error {
|
|
41
|
+
readonly task: Task<unknown>;
|
|
42
|
+
constructor(task: Task<unknown>);
|
|
43
|
+
}
|
|
44
|
+
/** The error for ai's answer: its status picks the class. */
|
|
45
|
+
export declare function errorFor(status: number, message: string, trace: string, retryAfter: number | null): SpredrError;
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { KeyObject } from 'node:crypto';
|
|
2
|
+
export { SpredrError } from './errors.js';
|
|
3
|
+
export type Auth = {
|
|
4
|
+
token: string;
|
|
5
|
+
} | {
|
|
6
|
+
from: string;
|
|
7
|
+
key: KeyObject;
|
|
8
|
+
};
|
|
9
|
+
export type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
10
|
+
/** How every side talks to ai. */
|
|
11
|
+
export interface ClientOptions {
|
|
12
|
+
/** A fetch of your own (a proxy, a test). */
|
|
13
|
+
fetch?: typeof fetch;
|
|
14
|
+
/** How long one request may take, in ms: 75 s by default, since a wait for a task is up to 60 s. */
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
/** How many more times a request is tried when that is safe: 2 by default; 0 never. */
|
|
17
|
+
maxRetries?: number;
|
|
18
|
+
/** The first wait before trying again, in ms, doubling each time (up to 8 s): 500 by default. */
|
|
19
|
+
retryDelayMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface CallOptions {
|
|
22
|
+
/** Whether sending it twice does the same as once. By default GET, PUT and DELETE do; a POST that carries its own key
|
|
23
|
+
* says true, a PUT that adds something each time says false. */
|
|
24
|
+
idempotent?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface Client {
|
|
27
|
+
call<T = unknown>(method: Method, path: string, body?: unknown, options?: CallOptions): Promise<T>;
|
|
28
|
+
/** The answer as text (an export, one JSON per line). */
|
|
29
|
+
text(method: 'GET', path: string): Promise<string>;
|
|
30
|
+
/** Bytes sent as they are (a session's file): PUT, signed over those bytes, its own headers beside them. */
|
|
31
|
+
upload<T = unknown>(path: string, data: Uint8Array, headers: Record<string, string>): Promise<T>;
|
|
32
|
+
/** Bytes back as they are, with their type (a session's file). */
|
|
33
|
+
download(path: string): Promise<{
|
|
34
|
+
data: Uint8Array;
|
|
35
|
+
type: string;
|
|
36
|
+
headers: Headers;
|
|
37
|
+
}>;
|
|
38
|
+
/** Server-sent events from a GET that stays open, one after another, after the event `lastId` (Last-Event-ID). Ends
|
|
39
|
+
* when the server closes it. */
|
|
40
|
+
events(path: string, lastId: number): AsyncGenerator<{
|
|
41
|
+
id: number;
|
|
42
|
+
event: string;
|
|
43
|
+
data: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
export declare function client(base: string, auth: Auth, options?: ClientOptions): Client;
|
|
47
|
+
/** A query string from the values that are set, encoded as it will be signed. */
|
|
48
|
+
export declare function query(values: Record<string, string | number | undefined>): string;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { Agent, type AgentAnswer, type AgentOptions, type Context, type Delivery, type Handler, type KindsOf, type Manifest } from './agent.js';
|
|
2
|
+
export { Caller, type Callback, type CallerOptions } from './caller.js';
|
|
3
|
+
export { AuthenticationError, BadRequestError, ConflictError, ConnectionError, InternalServerError, NotFoundError, PermissionDeniedError, RateLimitError, SpredrError, TaskError, TimeoutError, } from './errors.js';
|
|
4
|
+
export type { CallOptions, ClientOptions } from './http.js';
|
|
5
|
+
export { DEFAULT_AI_URL, OwnedAgent, Spredr, type SpredrOptions } from './owner.js';
|
|
6
|
+
export type { InferInput, InferOutput, StandardSchemaV1 } from './schema.js';
|
|
7
|
+
export { aiVerifier, newKeys, type Incoming } from './sign.js';
|
|
8
|
+
export { currentTask } from './tag.js';
|
|
9
|
+
export { Tasks, Tenant } from './tasks.js';
|
|
10
|
+
export type * from './types.js';
|