@zenera/neo 1.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 +21 -0
- package/README.md +178 -0
- package/dist/agent.d.ts +66 -0
- package/dist/agent.js +97 -0
- package/dist/architecture.d.ts +74 -0
- package/dist/architecture.js +105 -0
- package/dist/embedding.d.ts +60 -0
- package/dist/embedding.js +21 -0
- package/dist/embeddings/gemini.d.ts +24 -0
- package/dist/embeddings/gemini.js +71 -0
- package/dist/embeddings/index.d.ts +4 -0
- package/dist/embeddings/index.js +4 -0
- package/dist/embeddings/openai.d.ts +18 -0
- package/dist/embeddings/openai.js +27 -0
- package/dist/embeddings/openrouter.d.ts +21 -0
- package/dist/embeddings/openrouter.js +54 -0
- package/dist/events.d.ts +144 -0
- package/dist/events.js +110 -0
- package/dist/ids.d.ts +14 -0
- package/dist/ids.js +33 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +25 -0
- package/dist/inspect/client.d.ts +2 -0
- package/dist/inspect/client.js +1326 -0
- package/dist/inspect/css.d.ts +2 -0
- package/dist/inspect/css.js +164 -0
- package/dist/inspect/index.d.ts +9 -0
- package/dist/inspect/index.js +12 -0
- package/dist/inspect/page.d.ts +3 -0
- package/dist/inspect/page.js +93 -0
- package/dist/inspect/report.d.ts +54 -0
- package/dist/inspect/report.js +62 -0
- package/dist/kernel.d.ts +178 -0
- package/dist/kernel.js +929 -0
- package/dist/memory-stores/factory.d.ts +15 -0
- package/dist/memory-stores/factory.js +29 -0
- package/dist/memory-stores/file.d.ts +37 -0
- package/dist/memory-stores/file.js +174 -0
- package/dist/memory-stores/in-memory.d.ts +17 -0
- package/dist/memory-stores/in-memory.js +80 -0
- package/dist/memory-stores/index.d.ts +4 -0
- package/dist/memory-stores/index.js +5 -0
- package/dist/memory.d.ts +115 -0
- package/dist/memory.js +213 -0
- package/dist/model.d.ts +25 -0
- package/dist/model.js +2 -0
- package/dist/models/anthropic.d.ts +36 -0
- package/dist/models/anthropic.js +293 -0
- package/dist/models/factory.d.ts +202 -0
- package/dist/models/factory.js +533 -0
- package/dist/models/gemini.d.ts +45 -0
- package/dist/models/gemini.js +368 -0
- package/dist/models/index.d.ts +7 -0
- package/dist/models/index.js +7 -0
- package/dist/models/openai-chat.d.ts +19 -0
- package/dist/models/openai-chat.js +203 -0
- package/dist/models/openai-responses.d.ts +31 -0
- package/dist/models/openai-responses.js +258 -0
- package/dist/models/openrouter.d.ts +44 -0
- package/dist/models/openrouter.js +230 -0
- package/dist/payload-stores/factory.d.ts +15 -0
- package/dist/payload-stores/factory.js +30 -0
- package/dist/payload-stores/file.d.ts +29 -0
- package/dist/payload-stores/file.js +112 -0
- package/dist/payload-stores/in-memory.d.ts +17 -0
- package/dist/payload-stores/in-memory.js +40 -0
- package/dist/payload-stores/index.d.ts +4 -0
- package/dist/payload-stores/index.js +5 -0
- package/dist/payload.d.ts +89 -0
- package/dist/payload.js +181 -0
- package/dist/project/config.d.ts +302 -0
- package/dist/project/config.js +290 -0
- package/dist/project/index.d.ts +4 -0
- package/dist/project/index.js +4 -0
- package/dist/project/load.d.ts +142 -0
- package/dist/project/load.js +430 -0
- package/dist/project/refs.d.ts +23 -0
- package/dist/project/refs.js +70 -0
- package/dist/prompt.d.ts +66 -0
- package/dist/prompt.js +62 -0
- package/dist/runner.d.ts +103 -0
- package/dist/runner.js +537 -0
- package/dist/services.d.ts +23 -0
- package/dist/services.js +44 -0
- package/dist/skill-providers/factory.d.ts +16 -0
- package/dist/skill-providers/factory.js +26 -0
- package/dist/skill-providers/file.d.ts +44 -0
- package/dist/skill-providers/file.js +209 -0
- package/dist/skill-providers/index.d.ts +4 -0
- package/dist/skill-providers/index.js +5 -0
- package/dist/skill-providers/static.d.ts +13 -0
- package/dist/skill-providers/static.js +47 -0
- package/dist/skills.d.ts +102 -0
- package/dist/skills.js +232 -0
- package/dist/state.d.ts +86 -0
- package/dist/state.js +49 -0
- package/dist/tools/exa.d.ts +23 -0
- package/dist/tools/exa.js +389 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/sandbox.d.ts +172 -0
- package/dist/tools/sandbox.js +602 -0
- package/dist/tools/workspace.d.ts +53 -0
- package/dist/tools/workspace.js +1034 -0
- package/dist/trajectory.d.ts +213 -0
- package/dist/trajectory.js +232 -0
- package/dist/types.d.ts +195 -0
- package/dist/types.js +134 -0
- package/package.json +98 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { embeddingResponse, } from "../embedding.js";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Google Gemini embeddings adapter
|
|
4
|
+
//
|
|
5
|
+
// Serves `google` and `vertex` alike: the two differ in how the client
|
|
6
|
+
// authenticates, which is the provider's business, not this file's.
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
/**
|
|
9
|
+
* Google's task types are plain strings in `EmbedContentConfig` — unlike
|
|
10
|
+
* `ThinkingLevel` next door, there is no enum to inline. Only the retrieval
|
|
11
|
+
* pair is mapped: the others (clustering, similarity, classification) are jobs
|
|
12
|
+
* this runtime does not have a word for.
|
|
13
|
+
*/
|
|
14
|
+
const TASK_TYPES = {
|
|
15
|
+
query: 'RETRIEVAL_QUERY',
|
|
16
|
+
document: 'RETRIEVAL_DOCUMENT',
|
|
17
|
+
};
|
|
18
|
+
/** Requests in flight at once when a batch has to be split across several. */
|
|
19
|
+
const CONCURRENCY = 8;
|
|
20
|
+
export class GeminiEmbedder {
|
|
21
|
+
id;
|
|
22
|
+
#client;
|
|
23
|
+
#options;
|
|
24
|
+
constructor(id, client, options = {}) {
|
|
25
|
+
this.id = id;
|
|
26
|
+
this.#client = client;
|
|
27
|
+
this.#options = options;
|
|
28
|
+
}
|
|
29
|
+
async embed(req) {
|
|
30
|
+
const config = {
|
|
31
|
+
taskType: req.taskType ? TASK_TYPES[req.taskType] : undefined,
|
|
32
|
+
// Only meaningful alongside RETRIEVAL_DOCUMENT; the API ignores it
|
|
33
|
+
// otherwise rather than rejecting the request.
|
|
34
|
+
title: this.#options.title,
|
|
35
|
+
outputDimensionality: req.dimensions ?? this.#options.dimensions,
|
|
36
|
+
abortSignal: req.signal,
|
|
37
|
+
};
|
|
38
|
+
// The contract is batch-first and this endpoint usually is not, so the
|
|
39
|
+
// splitting happens here rather than in every caller. Chunks are issued
|
|
40
|
+
// in waves and their results concatenated in order, so a caller cannot
|
|
41
|
+
// tell how many requests it took.
|
|
42
|
+
const size = Math.max(1, this.#options.maxBatch ?? 1);
|
|
43
|
+
const chunks = [];
|
|
44
|
+
for (let i = 0; i < req.input.length; i += size) {
|
|
45
|
+
chunks.push(req.input.slice(i, i + size));
|
|
46
|
+
}
|
|
47
|
+
const vectors = [];
|
|
48
|
+
for (let i = 0; i < chunks.length; i += CONCURRENCY) {
|
|
49
|
+
const wave = await Promise.all(chunks.slice(i, i + CONCURRENCY).map((chunk) => this.#send(chunk, config)));
|
|
50
|
+
for (const part of wave) {
|
|
51
|
+
vectors.push(...part);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Usage stays undefined on purpose: this API reports billable
|
|
55
|
+
// *characters*, on Vertex only, which is not a token count and would be
|
|
56
|
+
// a lie in `TokenUsage`.
|
|
57
|
+
return embeddingResponse(vectors, req);
|
|
58
|
+
}
|
|
59
|
+
async #send(input, config) {
|
|
60
|
+
const res = await this.#client.models.embedContent({
|
|
61
|
+
model: this.id,
|
|
62
|
+
// Spelled out as one `Content` per text. `ContentListUnion` also
|
|
63
|
+
// accepts a `string[]`, and reads it as the *parts of a single
|
|
64
|
+
// document* — six sentences in, one vector back, and no error.
|
|
65
|
+
contents: input.map((text) => ({ parts: [{ text }] })),
|
|
66
|
+
config,
|
|
67
|
+
});
|
|
68
|
+
return (res.embeddings ?? []).map((e) => e.values ?? []);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=gemini.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type OpenAI from 'openai';
|
|
2
|
+
import { type Embedder, type EmbeddingRequest, type EmbeddingResponse } from '../embedding.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Provider-specific knobs. `taskType` has no counterpart here: OpenAI's models
|
|
5
|
+
* are symmetric, so a query and a document are encoded identically and the
|
|
6
|
+
* request's hint is simply not sent.
|
|
7
|
+
*/
|
|
8
|
+
export interface OpenAIEmbedderOptions {
|
|
9
|
+
/** default width; a request may override it */
|
|
10
|
+
dimensions?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class OpenAIEmbedder implements Embedder {
|
|
13
|
+
#private;
|
|
14
|
+
readonly id: string;
|
|
15
|
+
constructor(id: string, client: OpenAI, options?: OpenAIEmbedderOptions);
|
|
16
|
+
embed(req: EmbeddingRequest): Promise<EmbeddingResponse>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { embeddingResponse, } from "../embedding.js";
|
|
2
|
+
import { zeroUsage } from "../types.js";
|
|
3
|
+
export class OpenAIEmbedder {
|
|
4
|
+
id;
|
|
5
|
+
#client;
|
|
6
|
+
#dimensions;
|
|
7
|
+
constructor(id, client, options = {}) {
|
|
8
|
+
this.id = id;
|
|
9
|
+
this.#client = client;
|
|
10
|
+
this.#dimensions = options.dimensions;
|
|
11
|
+
}
|
|
12
|
+
async embed(req) {
|
|
13
|
+
const res = await this.#client.embeddings.create({
|
|
14
|
+
model: this.id,
|
|
15
|
+
input: req.input,
|
|
16
|
+
dimensions: req.dimensions ?? this.#dimensions,
|
|
17
|
+
}, { signal: req.signal });
|
|
18
|
+
// The API documents the order but does not promise it, and `index` is
|
|
19
|
+
// the only thing that ties a vector back to its text.
|
|
20
|
+
const vectors = [...res.data].sort((a, b) => a.index - b.index).map((d) => d.embedding);
|
|
21
|
+
return embeddingResponse(vectors, req, {
|
|
22
|
+
...zeroUsage(),
|
|
23
|
+
inputTokens: res.usage.prompt_tokens,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { OpenRouter } from '@openrouter/sdk';
|
|
2
|
+
import type { ProviderPreferences } from '@openrouter/sdk/models';
|
|
3
|
+
import type { Embedder, EmbeddingRequest, EmbeddingResponse } from '../embedding.ts';
|
|
4
|
+
/** Provider-specific knobs. */
|
|
5
|
+
export interface OpenRouterEmbedderOptions {
|
|
6
|
+
/** default width; a request may override it */
|
|
7
|
+
dimensions?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Which upstream providers may serve this model, and in what order. Named
|
|
10
|
+
* as in `OpenRouterModelOptions`, and for the same reason: a *provider*
|
|
11
|
+
* here is already the connection.
|
|
12
|
+
*/
|
|
13
|
+
routing?: ProviderPreferences;
|
|
14
|
+
}
|
|
15
|
+
export declare class OpenRouterEmbedder implements Embedder {
|
|
16
|
+
#private;
|
|
17
|
+
readonly id: string;
|
|
18
|
+
constructor(id: string, client: OpenRouter, options?: OpenRouterEmbedderOptions);
|
|
19
|
+
embed(req: EmbeddingRequest): Promise<EmbeddingResponse>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=openrouter.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { embeddingResponse } from "../embedding.js";
|
|
2
|
+
import { zeroUsage } from "../types.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// OpenRouter embeddings adapter
|
|
5
|
+
//
|
|
6
|
+
// The same trade as the chat adapter next door: its own SDK rather than the
|
|
7
|
+
// OpenAI client aimed at another base url, because provider routing is the
|
|
8
|
+
// reason to be here at all and chat completions has nowhere to put it.
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/** OpenRouter's word for the retrieval side, which it takes as a free string. */
|
|
11
|
+
const INPUT_TYPES = { query: 'search_query', document: 'search_document' };
|
|
12
|
+
export class OpenRouterEmbedder {
|
|
13
|
+
id;
|
|
14
|
+
#client;
|
|
15
|
+
#options;
|
|
16
|
+
constructor(id, client, options = {}) {
|
|
17
|
+
this.id = id;
|
|
18
|
+
this.#client = client;
|
|
19
|
+
this.#options = options;
|
|
20
|
+
}
|
|
21
|
+
async embed(req) {
|
|
22
|
+
const requestBody = {
|
|
23
|
+
model: this.id,
|
|
24
|
+
input: req.input,
|
|
25
|
+
dimensions: req.dimensions ?? this.#options.dimensions,
|
|
26
|
+
inputType: req.taskType ? INPUT_TYPES[req.taskType] : undefined,
|
|
27
|
+
provider: this.#options.routing,
|
|
28
|
+
// `encodingFormat` is deliberately not sent. Its type is an open
|
|
29
|
+
// enum, whose values are branded and so unreachable without a value
|
|
30
|
+
// import of the SDK — and float is the default anyway. The string
|
|
31
|
+
// branch of `embedding` below is what catches a gateway that
|
|
32
|
+
// decides otherwise.
|
|
33
|
+
};
|
|
34
|
+
const res = await this.#client.embeddings.generate({ requestBody }, { fetchOptions: { signal: req.signal } });
|
|
35
|
+
// The response is declared as the body *or* a bare string, so the
|
|
36
|
+
// parsed shape has to be established before anything is read off it.
|
|
37
|
+
if (typeof res === 'string') {
|
|
38
|
+
throw new Error(`embedder "${this.id}": expected an embeddings response, got text`);
|
|
39
|
+
}
|
|
40
|
+
const vectors = [...res.data].sort(byIndex).map((d) => vectorOf(d, this.id));
|
|
41
|
+
return embeddingResponse(vectors, req, res.usage ? { ...zeroUsage(), inputTokens: res.usage.promptTokens } : undefined);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** `index` is optional here, so its absence has to mean "keep the order given". */
|
|
45
|
+
function byIndex(a, b) {
|
|
46
|
+
return (a.index ?? 0) - (b.index ?? 0);
|
|
47
|
+
}
|
|
48
|
+
function vectorOf(data, id) {
|
|
49
|
+
if (typeof data.embedding === 'string') {
|
|
50
|
+
throw new Error(`embedder "${id}": got a base64 embedding, which this adapter does not decode`);
|
|
51
|
+
}
|
|
52
|
+
return data.embedding;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=openrouter.js.map
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { AgentState, RunResult } from './state.ts';
|
|
2
|
+
import type { ForkNode, JoinNode, LlmCallNode, ToolResultNode } from './trajectory.ts';
|
|
3
|
+
import type { Payload } from './payload.ts';
|
|
4
|
+
export interface BranchRef {
|
|
5
|
+
/** the fork that created this branch */
|
|
6
|
+
forkId: string;
|
|
7
|
+
/** declared branch name */
|
|
8
|
+
name: string;
|
|
9
|
+
/** the child run's id */
|
|
10
|
+
runId: string;
|
|
11
|
+
/** spec.forkDepth of the emitting run */
|
|
12
|
+
depth: number;
|
|
13
|
+
}
|
|
14
|
+
export interface EventBase {
|
|
15
|
+
/** emitting run (the root run id on the trunk) */
|
|
16
|
+
runId: string;
|
|
17
|
+
/** active agent in that run */
|
|
18
|
+
agent: string;
|
|
19
|
+
/** absent on the trunk; set on every event emitted by a branch */
|
|
20
|
+
branch?: BranchRef;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* What a `Model` produces while streaming. It carries no `EventBase`: a model
|
|
24
|
+
* knows nothing about runs or branches, so the runner tags these before they
|
|
25
|
+
* reach consumers.
|
|
26
|
+
*/
|
|
27
|
+
export type StreamDelta = {
|
|
28
|
+
type: 'thinking_delta';
|
|
29
|
+
delta: string;
|
|
30
|
+
} | {
|
|
31
|
+
type: 'text_delta';
|
|
32
|
+
delta: string;
|
|
33
|
+
} | {
|
|
34
|
+
type: 'tool_args_delta';
|
|
35
|
+
callId: string;
|
|
36
|
+
name: string;
|
|
37
|
+
delta: string;
|
|
38
|
+
argsSoFar: string;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'tool_call_detected';
|
|
41
|
+
callId: string;
|
|
42
|
+
name: string;
|
|
43
|
+
};
|
|
44
|
+
/** Fine-grained progress. Never required for correctness; safe to drop. */
|
|
45
|
+
export type StreamEvent = EventBase & StreamDelta;
|
|
46
|
+
/**
|
|
47
|
+
* Coarse-grained state transitions. The `state` in every checkpoint is a
|
|
48
|
+
* complete snapshot: persist it, and `runner.resume(state)` continues the run
|
|
49
|
+
* with no loss.
|
|
50
|
+
*/
|
|
51
|
+
export type CheckpointEvent = EventBase & ({
|
|
52
|
+
type: 'run_created';
|
|
53
|
+
state: AgentState;
|
|
54
|
+
} | {
|
|
55
|
+
type: 'before_llm_call';
|
|
56
|
+
state: AgentState;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'after_llm_call';
|
|
59
|
+
state: AgentState;
|
|
60
|
+
node: LlmCallNode;
|
|
61
|
+
} | {
|
|
62
|
+
type: 'before_tool_call';
|
|
63
|
+
state: AgentState;
|
|
64
|
+
call: PendingToolCall;
|
|
65
|
+
} | {
|
|
66
|
+
type: 'after_tool_call';
|
|
67
|
+
state: AgentState;
|
|
68
|
+
node: ToolResultNode;
|
|
69
|
+
} | {
|
|
70
|
+
type: 'handoff';
|
|
71
|
+
state: AgentState;
|
|
72
|
+
from: string;
|
|
73
|
+
to: string;
|
|
74
|
+
} | {
|
|
75
|
+
type: 'before_fork';
|
|
76
|
+
state: AgentState;
|
|
77
|
+
node: ForkNode;
|
|
78
|
+
} | {
|
|
79
|
+
type: 'branch_started';
|
|
80
|
+
state: AgentState;
|
|
81
|
+
child: BranchRef;
|
|
82
|
+
childState: AgentState;
|
|
83
|
+
} | {
|
|
84
|
+
type: 'branch_finished';
|
|
85
|
+
state: AgentState;
|
|
86
|
+
child: BranchRef;
|
|
87
|
+
childState: AgentState;
|
|
88
|
+
status: 'ok' | 'error' | 'aborted';
|
|
89
|
+
} | {
|
|
90
|
+
type: 'after_join';
|
|
91
|
+
state: AgentState;
|
|
92
|
+
node: JoinNode;
|
|
93
|
+
} | {
|
|
94
|
+
type: 'run_finished';
|
|
95
|
+
state: AgentState;
|
|
96
|
+
result: RunResult<unknown>;
|
|
97
|
+
});
|
|
98
|
+
export type AgentEvent = StreamEvent | CheckpointEvent;
|
|
99
|
+
export interface PendingToolCall {
|
|
100
|
+
callId: string;
|
|
101
|
+
name: string;
|
|
102
|
+
args: Payload;
|
|
103
|
+
}
|
|
104
|
+
export declare function isCheckpoint(e: AgentEvent): e is CheckpointEvent;
|
|
105
|
+
/**
|
|
106
|
+
* A run has two audiences: observers that want every step, and callers that
|
|
107
|
+
* only want the answer. `RunStream` serves both over a single generator.
|
|
108
|
+
*
|
|
109
|
+
* await runner.run(a, 'hi') // RunResult (thenable)
|
|
110
|
+
* await runner.run(a, 'hi').text() // string
|
|
111
|
+
* for await (const e of runner.run(a, 'hi')) {} // events
|
|
112
|
+
*/
|
|
113
|
+
export declare class RunStream<T = string> implements AsyncIterable<AgentEvent>, PromiseLike<RunResult<T>> {
|
|
114
|
+
#private;
|
|
115
|
+
constructor(gen: AsyncGenerator<AgentEvent, RunResult<T>>);
|
|
116
|
+
/**
|
|
117
|
+
* Iteration is single-pass and shared with `final()`: a partially consumed
|
|
118
|
+
* stream resumes where the loop stopped instead of re-running the agent.
|
|
119
|
+
*/
|
|
120
|
+
[Symbol.asyncIterator](): AsyncIterator<AgentEvent, RunResult<T> | undefined>;
|
|
121
|
+
/**
|
|
122
|
+
* Drains whatever events are left and yields the run's result. The `??=`
|
|
123
|
+
* memoizes, so calling it twice gives the same result.
|
|
124
|
+
*/
|
|
125
|
+
final(): Promise<RunResult<T>>;
|
|
126
|
+
text(): Promise<string>;
|
|
127
|
+
/**
|
|
128
|
+
* Implementing `then` makes the object a thenable, so `await` unwraps it
|
|
129
|
+
* exactly like a promise. Note this also starts draining the stream.
|
|
130
|
+
*/
|
|
131
|
+
then<A = RunResult<T>, B = never>(onOk?: ((r: RunResult<T>) => A | PromiseLike<A>) | null, onErr?: ((e: unknown) => B | PromiseLike<B>) | null): Promise<A | B>;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Branches run concurrently, so their events cannot be `yield*`-ed one stream
|
|
135
|
+
* at a time. They are pushed here instead and drained by the parent generator
|
|
136
|
+
* while it awaits the branch promises.
|
|
137
|
+
*/
|
|
138
|
+
export declare class EventQueue<T> {
|
|
139
|
+
#private;
|
|
140
|
+
push(v: T): void;
|
|
141
|
+
close(): void;
|
|
142
|
+
drain(): AsyncGenerator<T>;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=events.d.ts.map
|
package/dist/events.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export function isCheckpoint(e) {
|
|
2
|
+
return 'state' in e;
|
|
3
|
+
}
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// RunStream
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
/**
|
|
8
|
+
* A run has two audiences: observers that want every step, and callers that
|
|
9
|
+
* only want the answer. `RunStream` serves both over a single generator.
|
|
10
|
+
*
|
|
11
|
+
* await runner.run(a, 'hi') // RunResult (thenable)
|
|
12
|
+
* await runner.run(a, 'hi').text() // string
|
|
13
|
+
* for await (const e of runner.run(a, 'hi')) {} // events
|
|
14
|
+
*/
|
|
15
|
+
export class RunStream {
|
|
16
|
+
#gen;
|
|
17
|
+
#result;
|
|
18
|
+
#done;
|
|
19
|
+
constructor(gen) {
|
|
20
|
+
this.#gen = gen;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* `for await` discards the generator's *return* value, so it is latched here
|
|
24
|
+
* on the way past: a loop that runs to completion and a later `final()` then
|
|
25
|
+
* see the same result instead of `undefined`.
|
|
26
|
+
*/
|
|
27
|
+
async #next() {
|
|
28
|
+
if (this.#done) {
|
|
29
|
+
return { done: true, value: this.#done };
|
|
30
|
+
}
|
|
31
|
+
const step = await this.#gen.next();
|
|
32
|
+
if (step.done) {
|
|
33
|
+
this.#done = step.value;
|
|
34
|
+
}
|
|
35
|
+
return step;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Iteration is single-pass and shared with `final()`: a partially consumed
|
|
39
|
+
* stream resumes where the loop stopped instead of re-running the agent.
|
|
40
|
+
*/
|
|
41
|
+
[Symbol.asyncIterator]() {
|
|
42
|
+
return {
|
|
43
|
+
next: () => this.#next(),
|
|
44
|
+
// `break` calls this. Closing the underlying generator would abandon
|
|
45
|
+
// the run half-way, so the run is left alive on purpose — `final()`
|
|
46
|
+
// still drives it to the end. Cancellation belongs to the signal.
|
|
47
|
+
return: async () => ({ done: true, value: this.#done }),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Drains whatever events are left and yields the run's result. The `??=`
|
|
52
|
+
* memoizes, so calling it twice gives the same result.
|
|
53
|
+
*/
|
|
54
|
+
final() {
|
|
55
|
+
this.#result ??= (async () => {
|
|
56
|
+
for (;;) {
|
|
57
|
+
const step = await this.#next();
|
|
58
|
+
if (step.done) {
|
|
59
|
+
return step.value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
})();
|
|
63
|
+
return this.#result;
|
|
64
|
+
}
|
|
65
|
+
async text() {
|
|
66
|
+
const r = await this.final();
|
|
67
|
+
return typeof r.output === 'string' ? r.output : JSON.stringify(r.output);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Implementing `then` makes the object a thenable, so `await` unwraps it
|
|
71
|
+
* exactly like a promise. Note this also starts draining the stream.
|
|
72
|
+
*/
|
|
73
|
+
then(onOk, onErr) {
|
|
74
|
+
return this.final().then(onOk, onErr);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Branches run concurrently, so their events cannot be `yield*`-ed one stream
|
|
79
|
+
* at a time. They are pushed here instead and drained by the parent generator
|
|
80
|
+
* while it awaits the branch promises.
|
|
81
|
+
*/
|
|
82
|
+
export class EventQueue {
|
|
83
|
+
#items = [];
|
|
84
|
+
#wake;
|
|
85
|
+
#closed = false;
|
|
86
|
+
push(v) {
|
|
87
|
+
this.#items.push(v);
|
|
88
|
+
this.#wake?.();
|
|
89
|
+
this.#wake = undefined;
|
|
90
|
+
}
|
|
91
|
+
close() {
|
|
92
|
+
this.#closed = true;
|
|
93
|
+
this.#wake?.();
|
|
94
|
+
this.#wake = undefined;
|
|
95
|
+
}
|
|
96
|
+
async *drain() {
|
|
97
|
+
for (;;) {
|
|
98
|
+
while (this.#items.length) {
|
|
99
|
+
yield this.#items.shift();
|
|
100
|
+
}
|
|
101
|
+
if (this.#closed) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
await new Promise((resolve) => {
|
|
105
|
+
this.#wake = resolve;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=events.js.map
|
package/dist/ids.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All nondeterminism that the kernel needs (ids and wall clock) enters through
|
|
3
|
+
* this one interface, passed explicitly as an argument. Reading a clock from
|
|
4
|
+
* module scope would make replay-based hosts (Temporal) nondeterministic and
|
|
5
|
+
* would leak state between concurrent runs.
|
|
6
|
+
*/
|
|
7
|
+
export interface IdClock {
|
|
8
|
+
newId(): string;
|
|
9
|
+
now(): string;
|
|
10
|
+
}
|
|
11
|
+
/** Lexicographically sortable, collision-resistant id (ULID layout). */
|
|
12
|
+
export declare function ulid(now?: number): string;
|
|
13
|
+
export declare const systemClock: IdClock;
|
|
14
|
+
//# sourceMappingURL=ids.d.ts.map
|
package/dist/ids.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
// Crockford base32 — the ULID alphabet (no I, L, O, U).
|
|
3
|
+
const ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
|
|
4
|
+
const TIME_LEN = 10;
|
|
5
|
+
const RANDOM_LEN = 16;
|
|
6
|
+
function encodeTime(ms) {
|
|
7
|
+
let out = '';
|
|
8
|
+
let rest = ms;
|
|
9
|
+
for (let i = 0; i < TIME_LEN; i++) {
|
|
10
|
+
out = ALPHABET[rest % 32] + out;
|
|
11
|
+
rest = Math.floor(rest / 32);
|
|
12
|
+
}
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
15
|
+
function encodeRandom() {
|
|
16
|
+
// One byte per character wastes 3 bits each, which is irrelevant here and
|
|
17
|
+
// keeps the mapping obvious (no bit-packing arithmetic to get wrong).
|
|
18
|
+
const bytes = randomBytes(RANDOM_LEN);
|
|
19
|
+
let out = '';
|
|
20
|
+
for (const b of bytes) {
|
|
21
|
+
out += ALPHABET[b % 32];
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
/** Lexicographically sortable, collision-resistant id (ULID layout). */
|
|
26
|
+
export function ulid(now = Date.now()) {
|
|
27
|
+
return encodeTime(now) + encodeRandom();
|
|
28
|
+
}
|
|
29
|
+
export const systemClock = {
|
|
30
|
+
newId: () => ulid(),
|
|
31
|
+
now: () => new Date().toISOString(),
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=ids.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export * from './agent.ts';
|
|
2
|
+
export * from './architecture.ts';
|
|
3
|
+
export * from './embedding.ts';
|
|
4
|
+
export * from './embeddings/index.ts';
|
|
5
|
+
export * from './events.ts';
|
|
6
|
+
export * from './ids.ts';
|
|
7
|
+
export * from './inspect/index.ts';
|
|
8
|
+
export * as Kernel from './kernel.ts';
|
|
9
|
+
export * from './memory-stores/index.ts';
|
|
10
|
+
export * from './memory.ts';
|
|
11
|
+
export * from './model.ts';
|
|
12
|
+
export * from './models/index.ts';
|
|
13
|
+
export * from './payload-stores/index.ts';
|
|
14
|
+
export * from './payload.ts';
|
|
15
|
+
export * from './project/index.ts';
|
|
16
|
+
export * from './prompt.ts';
|
|
17
|
+
export * from './runner.ts';
|
|
18
|
+
export * from './services.ts';
|
|
19
|
+
export * from './skill-providers/index.ts';
|
|
20
|
+
export * from './skills.ts';
|
|
21
|
+
export * from './state.ts';
|
|
22
|
+
export * from './tools/index.ts';
|
|
23
|
+
export * from './trajectory.ts';
|
|
24
|
+
export * from './types.ts';
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export * from "./agent.js";
|
|
2
|
+
export * from "./architecture.js";
|
|
3
|
+
export * from "./embedding.js";
|
|
4
|
+
export * from "./embeddings/index.js";
|
|
5
|
+
export * from "./events.js";
|
|
6
|
+
export * from "./ids.js";
|
|
7
|
+
export * from "./inspect/index.js";
|
|
8
|
+
export * as Kernel from "./kernel.js";
|
|
9
|
+
export * from "./memory-stores/index.js";
|
|
10
|
+
export * from "./memory.js";
|
|
11
|
+
export * from "./model.js";
|
|
12
|
+
export * from "./models/index.js";
|
|
13
|
+
export * from "./payload-stores/index.js";
|
|
14
|
+
export * from "./payload.js";
|
|
15
|
+
export * from "./project/index.js";
|
|
16
|
+
export * from "./prompt.js";
|
|
17
|
+
export * from "./runner.js";
|
|
18
|
+
export * from "./services.js";
|
|
19
|
+
export * from "./skill-providers/index.js";
|
|
20
|
+
export * from "./skills.js";
|
|
21
|
+
export * from "./state.js";
|
|
22
|
+
export * from "./tools/index.js";
|
|
23
|
+
export * from "./trajectory.js";
|
|
24
|
+
export * from "./types.js";
|
|
25
|
+
//# sourceMappingURL=index.js.map
|