@dereekb/openrouter 13.37.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 +195 -0
- package/firebase/index.cjs.default.js +1 -0
- package/firebase/index.cjs.js +666 -0
- package/firebase/index.cjs.mjs +2 -0
- package/firebase/index.d.ts +1 -0
- package/firebase/index.esm.js +626 -0
- package/firebase/package.json +25 -0
- package/firebase/src/index.d.ts +1 -0
- package/firebase/src/lib/index.d.ts +4 -0
- package/firebase/src/lib/openrouter.api.d.ts +226 -0
- package/firebase/src/lib/openrouter.id.d.ts +56 -0
- package/firebase/src/lib/openrouter.model.d.ts +609 -0
- package/firebase/src/lib/openrouter.query.d.ts +121 -0
- package/firebase-server/index.cjs.default.js +1 -0
- package/firebase-server/index.cjs.js +4520 -0
- package/firebase-server/index.cjs.mjs +2 -0
- package/firebase-server/index.d.ts +1 -0
- package/firebase-server/index.esm.js +4466 -0
- package/firebase-server/package.json +38 -0
- package/firebase-server/src/index.d.ts +1 -0
- package/firebase-server/src/lib/index.d.ts +10 -0
- package/firebase-server/src/lib/openrouter.action.server.d.ts +196 -0
- package/firebase-server/src/lib/openrouter.broadcast.d.ts +93 -0
- package/firebase-server/src/lib/openrouter.call.inline.d.ts +57 -0
- package/firebase-server/src/lib/openrouter.file.attachment.d.ts +97 -0
- package/firebase-server/src/lib/openrouter.module.d.ts +65 -0
- package/firebase-server/src/lib/openrouter.prompt.service.d.ts +109 -0
- package/firebase-server/src/lib/openrouter.runtask.handle.d.ts +56 -0
- package/firebase-server/src/lib/openrouter.runtask.service.d.ts +380 -0
- package/firebase-server/src/lib/openrouter.runtask.sweep.d.ts +170 -0
- package/firebase-server/src/lib/openrouter.state.accessor.d.ts +106 -0
- package/firebase-server/src/test/openrouter.fake.d.ts +134 -0
- package/index.cjs.default.js +1 -0
- package/index.cjs.js +1867 -0
- package/index.cjs.mjs +2 -0
- package/index.d.ts +1 -0
- package/index.esm.js +1771 -0
- package/package.json +32 -0
- package/src/index.d.ts +1 -0
- package/src/lib/index.d.ts +10 -0
- package/src/lib/openrouter.call.d.ts +268 -0
- package/src/lib/openrouter.config.d.ts +314 -0
- package/src/lib/openrouter.embedding.d.ts +87 -0
- package/src/lib/openrouter.generation.d.ts +46 -0
- package/src/lib/openrouter.input.d.ts +238 -0
- package/src/lib/openrouter.prompt.d.ts +79 -0
- package/src/lib/openrouter.request.d.ts +91 -0
- package/src/lib/openrouter.sdk.d.ts +37 -0
- package/src/lib/openrouter.tool.d.ts +99 -0
- package/src/lib/openrouter.type.d.ts +125 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { type Maybe } from '@dereekb/util';
|
|
2
|
+
import { type ConversationState, type ConversationStatus, type OpenRouterAttachedFileReference, type OpenRouterInputMessage, type OpenRouterRunTaskKey, type StateAccessor, type Tool } from '@dereekb/openrouter';
|
|
3
|
+
import { type OpenRouterRunTask, type OpenRouterRunTaskDocument, OpenRouterRunTaskState } from '@dereekb/openrouter/firebase';
|
|
4
|
+
/**
|
|
5
|
+
* Maps a run task state to the SDK's conversation status.
|
|
6
|
+
*
|
|
7
|
+
* @param state - The run task state.
|
|
8
|
+
* @returns The conversation status.
|
|
9
|
+
*
|
|
10
|
+
* @__NO_SIDE_EFFECTS__
|
|
11
|
+
*/
|
|
12
|
+
export declare function conversationStatusForOpenRouterRunTaskState(state: OpenRouterRunTaskState): ConversationStatus;
|
|
13
|
+
/**
|
|
14
|
+
* Maps a conversation status back to the run task state to persist.
|
|
15
|
+
*
|
|
16
|
+
* @param status - The conversation status.
|
|
17
|
+
* @param hasPendingToolCalls - Whether the state carries tool calls this process cannot resolve.
|
|
18
|
+
* @returns The run task state.
|
|
19
|
+
*
|
|
20
|
+
* @__NO_SIDE_EFFECTS__
|
|
21
|
+
*/
|
|
22
|
+
export declare function openRouterRunTaskStateForConversationStatus(status: ConversationStatus, hasPendingToolCalls: boolean): OpenRouterRunTaskState;
|
|
23
|
+
/**
|
|
24
|
+
* Builds a {@link ConversationState} from a run task.
|
|
25
|
+
*
|
|
26
|
+
* `updatedAt` is derived rather than stored: the run task's existing timestamps already order the
|
|
27
|
+
* lifecycle (`fat` > `lat` > `sat` > `qat`), and the SDK uses the value informationally.
|
|
28
|
+
*
|
|
29
|
+
* @param key - The run task key, which is the conversation id.
|
|
30
|
+
* @param task - The run task.
|
|
31
|
+
* @returns The conversation state.
|
|
32
|
+
*
|
|
33
|
+
* @__NO_SIDE_EFFECTS__
|
|
34
|
+
*/
|
|
35
|
+
export declare function conversationStateForOpenRouterRunTask<TTools extends readonly Tool[] = readonly Tool[]>(key: OpenRouterRunTaskKey, task: OpenRouterRunTask): ConversationState<TTools>;
|
|
36
|
+
/**
|
|
37
|
+
* The subset of a run task that a conversation-state save writes.
|
|
38
|
+
*/
|
|
39
|
+
export type OpenRouterRunTaskStateUpdate = Pick<OpenRouterRunTask, 's' | 'msg' | 'ptc' | 'utr'>;
|
|
40
|
+
/**
|
|
41
|
+
* Builds the run task update for a conversation state.
|
|
42
|
+
*
|
|
43
|
+
* @param state - The conversation state to persist.
|
|
44
|
+
* @returns The fields to write.
|
|
45
|
+
*
|
|
46
|
+
* @__NO_SIDE_EFFECTS__
|
|
47
|
+
*/
|
|
48
|
+
export declare function openRouterRunTaskUpdateForConversationState(state: ConversationState): OpenRouterRunTaskStateUpdate;
|
|
49
|
+
/**
|
|
50
|
+
* Strips `undefined` out of a value on its way into Firestore, at ANY DEPTH.
|
|
51
|
+
*
|
|
52
|
+
* Conversation state is whatever the SDK hands back, arbitrarily nested, and its response items carry
|
|
53
|
+
* explicit `undefined`s for absent optional fields at every level. Firestore rejects `undefined` outright,
|
|
54
|
+
* so persisting one unfiltered fails the whole write — and it fails inside the SDK's `saveStateSafely`,
|
|
55
|
+
* which surfaces as an opaque "Failed to persist conversation state" rather than as the run-task write it
|
|
56
|
+
* actually is.
|
|
57
|
+
*
|
|
58
|
+
* A JSON round-trip rather than `copyValueWithoutUndefinedValues` (which filters just as deeply, and is
|
|
59
|
+
* what the run task converter's passthrough-JSON fields use): the round-trip additionally flattens
|
|
60
|
+
* anything that is not wire json — a `Date`, a class instance with a `toJSON` — which is correct here
|
|
61
|
+
* precisely because this data IS json. It came off the wire, and `load()` hands it straight back to the
|
|
62
|
+
* SDK expecting the same shapes. The converter's fields, by contrast, must leave a `Date`/`Timestamp`
|
|
63
|
+
* intact for Firestore.
|
|
64
|
+
*
|
|
65
|
+
* @param value - The value to sanitize.
|
|
66
|
+
* @returns The value with every `undefined` removed.
|
|
67
|
+
*
|
|
68
|
+
* @__NO_SIDE_EFFECTS__
|
|
69
|
+
*/
|
|
70
|
+
export declare function openRouterConversationValueForFirestore<T>(value: T): T;
|
|
71
|
+
/**
|
|
72
|
+
* Config for {@link firestoreOpenRouterStateAccessor}.
|
|
73
|
+
*/
|
|
74
|
+
export interface FirestoreOpenRouterStateAccessorConfig {
|
|
75
|
+
/**
|
|
76
|
+
* The conversation to start from when the run task has no history yet.
|
|
77
|
+
*
|
|
78
|
+
* The SDK never records the request's own input into conversation state — it only appends what comes
|
|
79
|
+
* BACK — so a run that resumes from state alone would resume having forgotten what it was asked. The
|
|
80
|
+
* runner seeds the assembled request input here so the persisted conversation is the whole
|
|
81
|
+
* conversation, and passes an empty `input` on the request itself to avoid sending it twice.
|
|
82
|
+
*/
|
|
83
|
+
readonly initialMessages?: Maybe<OpenRouterInputMessage[]>;
|
|
84
|
+
/**
|
|
85
|
+
* The files attached for THIS attempt.
|
|
86
|
+
*
|
|
87
|
+
* Loaded history is re-pointed at these attachments, so a resume hours later does not replay a signed
|
|
88
|
+
* url that expired minutes after the attempt that persisted it — or, in inline mode, a part whose
|
|
89
|
+
* payload was deliberately stripped on save.
|
|
90
|
+
*/
|
|
91
|
+
readonly attachedFiles?: Maybe<OpenRouterAttachedFileReference[]>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Creates a {@link StateAccessor} backed by a run task document.
|
|
95
|
+
*
|
|
96
|
+
* This is the persistent backend the SDK's docs ask for — its own example is a `Map`, with the note to
|
|
97
|
+
* "implement `StateAccessor` with a persistent backend". Because OpenRouter allocates no conversation
|
|
98
|
+
* id (and rejects `previous_response_id` outright), the conversation id is ours: the run task key.
|
|
99
|
+
*
|
|
100
|
+
* A single-shot run simply never populates `msg` / `ptc` / `utr`, so nothing is paid for not using it.
|
|
101
|
+
*
|
|
102
|
+
* @param document - The run task document to read and write.
|
|
103
|
+
* @param config - The initial conversation and this attempt's attached files.
|
|
104
|
+
* @returns The state accessor.
|
|
105
|
+
*/
|
|
106
|
+
export declare function firestoreOpenRouterStateAccessor<TTools extends readonly Tool[] = readonly Tool[]>(document: OpenRouterRunTaskDocument, config?: Maybe<FirestoreOpenRouterStateAccessorConfig>): StateAccessor<TTools>;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test doubles for the emulator integration suite.
|
|
3
|
+
*
|
|
4
|
+
* The OpenRouter client faked here is a REAL `OpenRouterCore` wired to a stub `fetcher` rather than a
|
|
5
|
+
* hand-rolled object. That matters: every scenario that asserts something about the outgoing request
|
|
6
|
+
* (a freshly signed url, an echoed annotation, a trace attribute) is then asserting against the JSON
|
|
7
|
+
* OpenRouter would actually receive, after the SDK's own outbound serialization — which is where a
|
|
8
|
+
* field silently gets dropped. A stubbed `callModel` would assert against our own intermediate shape
|
|
9
|
+
* and prove nothing about the wire.
|
|
10
|
+
*/
|
|
11
|
+
import { OpenRouterCore } from '@openrouter/sdk/core';
|
|
12
|
+
import { type FirebaseStorageContext } from '@dereekb/firebase';
|
|
13
|
+
import { type Maybe } from '@dereekb/util';
|
|
14
|
+
/**
|
|
15
|
+
* A tool call the fake model should emit.
|
|
16
|
+
*/
|
|
17
|
+
export interface FakeOpenRouterToolCall {
|
|
18
|
+
readonly callId: string;
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly arguments?: Maybe<Record<string, unknown>>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* What the fake model should answer with on one turn.
|
|
24
|
+
*/
|
|
25
|
+
export interface FakeOpenRouterReply {
|
|
26
|
+
readonly id?: Maybe<string>;
|
|
27
|
+
readonly text?: Maybe<string>;
|
|
28
|
+
readonly toolCalls?: Maybe<FakeOpenRouterToolCall[]>;
|
|
29
|
+
/**
|
|
30
|
+
* A response-level error, which the runner treats as a failed attempt.
|
|
31
|
+
*
|
|
32
|
+
* `code` is a string because OpenRouter's `ResponsesErrorField` models it as one — a numeric HTTP
|
|
33
|
+
* status here fails the SDK's inbound validation and produces a transport error instead of the
|
|
34
|
+
* response-level error the test meant to exercise.
|
|
35
|
+
*/
|
|
36
|
+
readonly error?: Maybe<{
|
|
37
|
+
readonly code: string;
|
|
38
|
+
readonly message: string;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Cost/usage to report.
|
|
42
|
+
*/
|
|
43
|
+
readonly cost?: Maybe<number>;
|
|
44
|
+
/**
|
|
45
|
+
* Milliseconds to stall before answering, for the time-budget and concurrency scenarios.
|
|
46
|
+
*/
|
|
47
|
+
readonly delayMs?: Maybe<number>;
|
|
48
|
+
/**
|
|
49
|
+
* Thrown instead of answered, for the transport-failure path.
|
|
50
|
+
*/
|
|
51
|
+
readonly throws?: Maybe<Error>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Decides the reply for one request. Receives the request body exactly as it went on the wire.
|
|
55
|
+
*/
|
|
56
|
+
export type FakeOpenRouterReplyFactory = (body: Record<string, unknown>, callIndex: number) => FakeOpenRouterReply | Promise<FakeOpenRouterReply>;
|
|
57
|
+
/**
|
|
58
|
+
* A fake OpenRouter client plus the requests it received.
|
|
59
|
+
*/
|
|
60
|
+
export interface FakeOpenRouterClient {
|
|
61
|
+
readonly client: OpenRouterCore;
|
|
62
|
+
/**
|
|
63
|
+
* Every request body sent, in order, serialized exactly as OpenRouter would have received it.
|
|
64
|
+
*/
|
|
65
|
+
readonly requests: Record<string, unknown>[];
|
|
66
|
+
readonly callCount: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Builds an `OpenResponsesResult` JSON body in the wire (snake_case) shape the SDK's inbound schema
|
|
70
|
+
* parses.
|
|
71
|
+
*
|
|
72
|
+
* @param reply - What the fake model should answer with.
|
|
73
|
+
* @param index - The call ordinal, used to make a distinct generation id when none is given.
|
|
74
|
+
* @returns The response body.
|
|
75
|
+
*/
|
|
76
|
+
export declare function fakeOpenRouterResponseBody(reply: FakeOpenRouterReply, index: number): Record<string, unknown>;
|
|
77
|
+
/**
|
|
78
|
+
* Creates a real {@link OpenRouterCore} whose HTTP layer is answered locally.
|
|
79
|
+
*
|
|
80
|
+
* @param replyFactory - Decides the reply per request, or a single fixed reply.
|
|
81
|
+
* @returns The client and its captured requests.
|
|
82
|
+
*/
|
|
83
|
+
export declare function fakeOpenRouterClient(replyFactory: FakeOpenRouterReplyFactory | FakeOpenRouterReply): FakeOpenRouterClient;
|
|
84
|
+
/**
|
|
85
|
+
* One object held by a {@link FakeStorageContext}.
|
|
86
|
+
*/
|
|
87
|
+
export interface FakeStorageObject {
|
|
88
|
+
readonly bytes: Uint8Array;
|
|
89
|
+
readonly contentType?: Maybe<string>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A read of an object's bytes, with the cap the caller asked for.
|
|
93
|
+
*/
|
|
94
|
+
export interface FakeStorageGetBytesCall {
|
|
95
|
+
readonly pathString: string;
|
|
96
|
+
readonly maxDownloadSizeBytes?: Maybe<number>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A storage context that mints a distinct, timestamped url per call and serves in-memory bytes.
|
|
100
|
+
*
|
|
101
|
+
* The emulator's storage cannot mint a real signed url, and a real one would not answer the question
|
|
102
|
+
* the signed-url scenario asks anyway: it asks whether the runner mints a NEW url per attempt, which is
|
|
103
|
+
* observable only by making every mint distinguishable.
|
|
104
|
+
*/
|
|
105
|
+
export interface FakeStorageContext {
|
|
106
|
+
readonly storageContext: FirebaseStorageContext;
|
|
107
|
+
/**
|
|
108
|
+
* The urls minted so far, in order.
|
|
109
|
+
*/
|
|
110
|
+
readonly signed: string[];
|
|
111
|
+
/**
|
|
112
|
+
* Every `getBytes` made, in order, with the cap it was made under.
|
|
113
|
+
*/
|
|
114
|
+
readonly reads: FakeStorageGetBytesCall[];
|
|
115
|
+
/**
|
|
116
|
+
* The in-memory objects, by path string.
|
|
117
|
+
*/
|
|
118
|
+
readonly objects: Record<string, FakeStorageObject>;
|
|
119
|
+
/**
|
|
120
|
+
* Seeds an object at a path.
|
|
121
|
+
*/
|
|
122
|
+
putObject(pathString: string, object: FakeStorageObject): void;
|
|
123
|
+
/**
|
|
124
|
+
* Overridable clock, so a test can advance past a signed url's lifetime.
|
|
125
|
+
*/
|
|
126
|
+
now: () => number;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Creates a {@link FakeStorageContext}.
|
|
130
|
+
*
|
|
131
|
+
* @param bucketId - The default bucket id to report.
|
|
132
|
+
* @returns The fake storage context.
|
|
133
|
+
*/
|
|
134
|
+
export declare function fakeStorageContext(bucketId?: string): FakeStorageContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
exports._default = require('./index.cjs.js').default;
|