agents 0.0.0-293b546 → 0.0.0-29938d4
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/README.md +121 -0
- package/dist/ai-chat-agent.d.ts +158 -24
- package/dist/ai-chat-agent.js +380 -60
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.js +154 -2
- package/dist/ai-chat-v5-migration.js.map +1 -0
- package/dist/ai-react.d.ts +136 -16
- package/dist/ai-react.js +252 -74
- package/dist/ai-react.js.map +1 -1
- package/dist/{ai-types-81H_-Uxh.d.ts → ai-types-0OnT3FHg.d.ts} +26 -2
- package/dist/{ai-types-CrMqkwc_.js → ai-types-DEtF_8Km.js} +5 -1
- package/dist/ai-types-DEtF_8Km.js.map +1 -0
- package/dist/ai-types.d.ts +1 -1
- package/dist/ai-types.js +1 -1
- package/dist/cli/index.d.ts +1 -0
- package/dist/{cli.js → cli/index.js} +7 -6
- package/dist/cli/index.js.map +1 -0
- package/dist/{client-BAQA84dr.d.ts → client-CdM5I962.d.ts} +2 -2
- package/dist/client-DFotUKH_.d.ts +834 -0
- package/dist/{client-B3SR12TQ.js → client-DjTPRM8-.js} +2 -2
- package/dist/{client-B3SR12TQ.js.map → client-DjTPRM8-.js.map} +1 -1
- package/dist/{client-C8VrzljV.js → client-QZa2Rq0l.js} +371 -187
- package/dist/client-QZa2Rq0l.js.map +1 -0
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/codemode/ai.js +6 -6
- package/dist/codemode/ai.js.map +1 -1
- package/dist/context-BkKbAa1R.js +8 -0
- package/dist/context-BkKbAa1R.js.map +1 -0
- package/dist/context-DcbQ8o7k.d.ts +24 -0
- package/dist/context.d.ts +6 -0
- package/dist/context.js +3 -0
- package/dist/{do-oauth-client-provider-C2CHH5x-.d.ts → do-oauth-client-provider--To1Tsjj.d.ts} +20 -5
- package/dist/{do-oauth-client-provider-CwqK5SXm.js → do-oauth-client-provider-B1fVIshX.js} +69 -8
- package/dist/do-oauth-client-provider-B1fVIshX.js.map +1 -0
- package/dist/{index-7kI1zprE.d.ts → index-CT2tCrLr.d.ts} +59 -60
- package/dist/{index-BUle9RiP.d.ts → index-DLuxm_9W.d.ts} +2 -2
- package/dist/index.d.ts +31 -34
- package/dist/index.js +5 -5
- package/dist/mcp/client.d.ts +2 -4
- package/dist/mcp/client.js +2 -2
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/do-oauth-client-provider.js +1 -1
- package/dist/mcp/index.d.ts +19 -12
- package/dist/mcp/index.js +55 -60
- package/dist/mcp/index.js.map +1 -1
- package/dist/{mcp-BwPscEiF.d.ts → mcp-CPSfGUgd.d.ts} +1 -1
- package/dist/observability/index.d.ts +1 -2
- package/dist/observability/index.js +5 -5
- package/dist/react.d.ts +134 -10
- package/dist/react.js +56 -56
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +18 -72
- package/dist/{serializable-faDkMCai.d.ts → serializable-Crsj26mx.d.ts} +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{src-xjQt2wBU.js → src-BZDh910Z.js} +26 -25
- package/dist/src-BZDh910Z.js.map +1 -0
- package/package.json +29 -14
- package/dist/ai-chat-v5-migration-BSiGZmYU.js +0 -155
- package/dist/ai-chat-v5-migration-BSiGZmYU.js.map +0 -1
- package/dist/ai-types-CrMqkwc_.js.map +0 -1
- package/dist/cli.d.ts +0 -8
- package/dist/cli.js.map +0 -1
- package/dist/client-BG2wUgN5.d.ts +0 -1462
- package/dist/client-C8VrzljV.js.map +0 -1
- package/dist/do-oauth-client-provider-CwqK5SXm.js.map +0 -1
- package/dist/react-9nVfoERh.d.ts +0 -113
- package/dist/src-xjQt2wBU.js.map +0 -1
package/dist/react.d.ts
CHANGED
|
@@ -1,10 +1,134 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import "./
|
|
3
|
-
import "./
|
|
4
|
-
import "./index-
|
|
5
|
-
import "./
|
|
6
|
-
import "./
|
|
7
|
-
import "
|
|
8
|
-
import "
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import "./context-DcbQ8o7k.js";
|
|
2
|
+
import "./client-DFotUKH_.js";
|
|
3
|
+
import "./ai-types-0OnT3FHg.js";
|
|
4
|
+
import { p as MCPServersState, t as Agent } from "./index-CT2tCrLr.js";
|
|
5
|
+
import { n as RPCMethod, t as Method } from "./serializable-Crsj26mx.js";
|
|
6
|
+
import { i as StreamOptions } from "./client-CdM5I962.js";
|
|
7
|
+
import { PartySocket } from "partysocket";
|
|
8
|
+
import { usePartySocket } from "partysocket/react";
|
|
9
|
+
|
|
10
|
+
//#region src/react.d.ts
|
|
11
|
+
type QueryObject = Record<string, string | null>;
|
|
12
|
+
interface CacheEntry {
|
|
13
|
+
promise: Promise<QueryObject>;
|
|
14
|
+
expiresAt: number;
|
|
15
|
+
}
|
|
16
|
+
declare function getCacheEntry(key: string): CacheEntry | undefined;
|
|
17
|
+
declare function setCacheEntry(
|
|
18
|
+
key: string,
|
|
19
|
+
promise: Promise<QueryObject>,
|
|
20
|
+
cacheTtl: number
|
|
21
|
+
): CacheEntry;
|
|
22
|
+
declare function deleteCacheEntry(key: string): void;
|
|
23
|
+
declare const _testUtils: {
|
|
24
|
+
queryCache: Map<string, CacheEntry>;
|
|
25
|
+
setCacheEntry: typeof setCacheEntry;
|
|
26
|
+
getCacheEntry: typeof getCacheEntry;
|
|
27
|
+
deleteCacheEntry: typeof deleteCacheEntry;
|
|
28
|
+
clearCache: () => void;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Options for the useAgent hook
|
|
32
|
+
* @template State Type of the Agent's state
|
|
33
|
+
*/
|
|
34
|
+
type UseAgentOptions<State = unknown> = Omit<
|
|
35
|
+
Parameters<typeof usePartySocket>[0],
|
|
36
|
+
"party" | "room" | "query"
|
|
37
|
+
> & {
|
|
38
|
+
/** Name of the agent to connect to */
|
|
39
|
+
agent: string;
|
|
40
|
+
/** Name of the specific Agent instance */
|
|
41
|
+
name?: string;
|
|
42
|
+
/** Query parameters - can be static object or async function */
|
|
43
|
+
query?: QueryObject | (() => Promise<QueryObject>);
|
|
44
|
+
/** Dependencies for async query caching */
|
|
45
|
+
queryDeps?: unknown[];
|
|
46
|
+
/** Cache TTL in milliseconds for auth tokens/time-sensitive data */
|
|
47
|
+
cacheTtl?: number;
|
|
48
|
+
/** Called when the Agent's state is updated */
|
|
49
|
+
onStateUpdate?: (state: State, source: "server" | "client") => void;
|
|
50
|
+
/** Called when MCP server state is updated */
|
|
51
|
+
onMcpUpdate?: (mcpServers: MCPServersState) => void;
|
|
52
|
+
};
|
|
53
|
+
type AllOptional<T> = T extends [infer A, ...infer R]
|
|
54
|
+
? undefined extends A
|
|
55
|
+
? AllOptional<R>
|
|
56
|
+
: false
|
|
57
|
+
: true;
|
|
58
|
+
type RPCMethods<T> = {
|
|
59
|
+
[K in keyof T as T[K] extends RPCMethod<T[K]> ? K : never]: RPCMethod<T[K]>;
|
|
60
|
+
};
|
|
61
|
+
type OptionalParametersMethod<T extends RPCMethod> =
|
|
62
|
+
AllOptional<Parameters<T>> extends true ? T : never;
|
|
63
|
+
type AgentMethods<T> = Omit<RPCMethods<T>, keyof Agent<any, any>>;
|
|
64
|
+
type OptionalAgentMethods<T> = {
|
|
65
|
+
[K in keyof AgentMethods<T> as AgentMethods<T>[K] extends OptionalParametersMethod<
|
|
66
|
+
AgentMethods<T>[K]
|
|
67
|
+
>
|
|
68
|
+
? K
|
|
69
|
+
: never]: OptionalParametersMethod<AgentMethods<T>[K]>;
|
|
70
|
+
};
|
|
71
|
+
type RequiredAgentMethods<T> = Omit<
|
|
72
|
+
AgentMethods<T>,
|
|
73
|
+
keyof OptionalAgentMethods<T>
|
|
74
|
+
>;
|
|
75
|
+
type AgentPromiseReturnType<T, K$1 extends keyof AgentMethods<T>> =
|
|
76
|
+
ReturnType<AgentMethods<T>[K$1]> extends Promise<any>
|
|
77
|
+
? ReturnType<AgentMethods<T>[K$1]>
|
|
78
|
+
: Promise<ReturnType<AgentMethods<T>[K$1]>>;
|
|
79
|
+
type OptionalArgsAgentMethodCall<AgentT> = <
|
|
80
|
+
K$1 extends keyof OptionalAgentMethods<AgentT>
|
|
81
|
+
>(
|
|
82
|
+
method: K$1,
|
|
83
|
+
args?: Parameters<OptionalAgentMethods<AgentT>[K$1]>,
|
|
84
|
+
streamOptions?: StreamOptions
|
|
85
|
+
) => AgentPromiseReturnType<AgentT, K$1>;
|
|
86
|
+
type RequiredArgsAgentMethodCall<AgentT> = <
|
|
87
|
+
K$1 extends keyof RequiredAgentMethods<AgentT>
|
|
88
|
+
>(
|
|
89
|
+
method: K$1,
|
|
90
|
+
args: Parameters<RequiredAgentMethods<AgentT>[K$1]>,
|
|
91
|
+
streamOptions?: StreamOptions
|
|
92
|
+
) => AgentPromiseReturnType<AgentT, K$1>;
|
|
93
|
+
type AgentMethodCall<AgentT> = OptionalArgsAgentMethodCall<AgentT> &
|
|
94
|
+
RequiredArgsAgentMethodCall<AgentT>;
|
|
95
|
+
type UntypedAgentMethodCall = <T = unknown>(
|
|
96
|
+
method: string,
|
|
97
|
+
args?: unknown[],
|
|
98
|
+
streamOptions?: StreamOptions
|
|
99
|
+
) => Promise<T>;
|
|
100
|
+
type AgentStub<T> = {
|
|
101
|
+
[K in keyof AgentMethods<T>]: (
|
|
102
|
+
...args: Parameters<AgentMethods<T>[K]>
|
|
103
|
+
) => AgentPromiseReturnType<AgentMethods<T>, K>;
|
|
104
|
+
};
|
|
105
|
+
type UntypedAgentStub = Record<string, Method>;
|
|
106
|
+
/**
|
|
107
|
+
* React hook for connecting to an Agent
|
|
108
|
+
*/
|
|
109
|
+
declare function useAgent<State = unknown>(
|
|
110
|
+
options: UseAgentOptions<State>
|
|
111
|
+
): PartySocket & {
|
|
112
|
+
agent: string;
|
|
113
|
+
name: string;
|
|
114
|
+
setState: (state: State) => void;
|
|
115
|
+
call: UntypedAgentMethodCall;
|
|
116
|
+
stub: UntypedAgentStub;
|
|
117
|
+
};
|
|
118
|
+
declare function useAgent<
|
|
119
|
+
AgentT extends {
|
|
120
|
+
get state(): State;
|
|
121
|
+
},
|
|
122
|
+
State
|
|
123
|
+
>(
|
|
124
|
+
options: UseAgentOptions<State>
|
|
125
|
+
): PartySocket & {
|
|
126
|
+
agent: string;
|
|
127
|
+
name: string;
|
|
128
|
+
setState: (state: State) => void;
|
|
129
|
+
call: AgentMethodCall<AgentT>;
|
|
130
|
+
stub: AgentStub<AgentT>;
|
|
131
|
+
};
|
|
132
|
+
//#endregion
|
|
133
|
+
export { UseAgentOptions, _testUtils, useAgent };
|
|
134
|
+
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as MessageType } from "./ai-types-
|
|
2
|
-
import { use, useCallback, useEffect, useMemo, useRef } from "react";
|
|
1
|
+
import { t as MessageType } from "./ai-types-DEtF_8Km.js";
|
|
2
|
+
import { use, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { usePartySocket } from "partysocket/react";
|
|
4
4
|
|
|
5
5
|
//#region src/react.tsx
|
|
@@ -15,78 +15,83 @@ function camelCaseToKebabCase(str) {
|
|
|
15
15
|
return kebabified.replace(/_/g, "-").replace(/-$/, "");
|
|
16
16
|
}
|
|
17
17
|
const queryCache = /* @__PURE__ */ new Map();
|
|
18
|
-
function arraysEqual(a, b) {
|
|
19
|
-
if (a === b) return true;
|
|
20
|
-
if (a.length !== b.length) return false;
|
|
21
|
-
for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
function findCacheEntry(targetKey) {
|
|
25
|
-
for (const [existingKey, entry] of queryCache.entries()) if (arraysEqual(existingKey, targetKey)) {
|
|
26
|
-
if (Date.now() > entry.expiresAt) {
|
|
27
|
-
queryCache.delete(existingKey);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
entry.refCount++;
|
|
31
|
-
return entry.promise;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function setCacheEntry(key, value, cacheTtl) {
|
|
35
|
-
for (const [existingKey] of queryCache.entries()) if (arraysEqual(existingKey, key)) {
|
|
36
|
-
queryCache.delete(existingKey);
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
const expiresAt = cacheTtl ? Date.now() + cacheTtl : Date.now() + 300 * 1e3;
|
|
40
|
-
queryCache.set(key, {
|
|
41
|
-
promise: value,
|
|
42
|
-
refCount: 1,
|
|
43
|
-
expiresAt,
|
|
44
|
-
cacheTtl
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
function decrementCacheEntry(targetKey) {
|
|
48
|
-
for (const [existingKey, entry] of queryCache.entries()) if (arraysEqual(existingKey, targetKey)) {
|
|
49
|
-
entry.refCount--;
|
|
50
|
-
if (entry.refCount <= 0) queryCache.delete(existingKey);
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
18
|
function createCacheKey(agentNamespace, name, deps) {
|
|
56
|
-
return [
|
|
19
|
+
return JSON.stringify([
|
|
57
20
|
agentNamespace,
|
|
58
21
|
name || "default",
|
|
59
22
|
...deps
|
|
60
|
-
];
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
function getCacheEntry(key) {
|
|
26
|
+
const entry = queryCache.get(key);
|
|
27
|
+
if (!entry) return void 0;
|
|
28
|
+
if (Date.now() >= entry.expiresAt) {
|
|
29
|
+
queryCache.delete(key);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
return entry;
|
|
33
|
+
}
|
|
34
|
+
function setCacheEntry(key, promise, cacheTtl) {
|
|
35
|
+
const entry = {
|
|
36
|
+
promise,
|
|
37
|
+
expiresAt: Date.now() + cacheTtl
|
|
38
|
+
};
|
|
39
|
+
queryCache.set(key, entry);
|
|
40
|
+
return entry;
|
|
61
41
|
}
|
|
42
|
+
function deleteCacheEntry(key) {
|
|
43
|
+
queryCache.delete(key);
|
|
44
|
+
}
|
|
45
|
+
const _testUtils = {
|
|
46
|
+
queryCache,
|
|
47
|
+
setCacheEntry,
|
|
48
|
+
getCacheEntry,
|
|
49
|
+
deleteCacheEntry,
|
|
50
|
+
clearCache: () => queryCache.clear()
|
|
51
|
+
};
|
|
62
52
|
function useAgent(options) {
|
|
63
53
|
const agentNamespace = camelCaseToKebabCase(options.agent);
|
|
64
54
|
const { query, queryDeps, cacheTtl, ...restOptions } = options;
|
|
65
55
|
const pendingCallsRef = useRef(/* @__PURE__ */ new Map());
|
|
66
|
-
const cacheKey = useMemo(() =>
|
|
67
|
-
const deps = queryDeps || [];
|
|
68
|
-
return createCacheKey(agentNamespace, options.name, deps);
|
|
69
|
-
}, [
|
|
56
|
+
const cacheKey = useMemo(() => createCacheKey(agentNamespace, options.name, queryDeps || []), [
|
|
70
57
|
agentNamespace,
|
|
71
58
|
options.name,
|
|
72
59
|
queryDeps
|
|
73
60
|
]);
|
|
61
|
+
const ttl = cacheTtl ?? 300 * 1e3;
|
|
62
|
+
const [cacheInvalidatedAt, setCacheInvalidatedAt] = useState(0);
|
|
74
63
|
const queryPromise = useMemo(() => {
|
|
75
64
|
if (!query || typeof query !== "function") return null;
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
65
|
+
const cached = getCacheEntry(cacheKey);
|
|
66
|
+
if (cached) return cached.promise;
|
|
78
67
|
const promise = query().catch((error) => {
|
|
79
68
|
console.error(`[useAgent] Query failed for agent "${options.agent}":`, error);
|
|
80
|
-
|
|
69
|
+
deleteCacheEntry(cacheKey);
|
|
81
70
|
throw error;
|
|
82
71
|
});
|
|
83
|
-
setCacheEntry(cacheKey, promise,
|
|
72
|
+
setCacheEntry(cacheKey, promise, ttl);
|
|
84
73
|
return promise;
|
|
85
74
|
}, [
|
|
86
75
|
cacheKey,
|
|
87
76
|
query,
|
|
88
77
|
options.agent,
|
|
89
|
-
|
|
78
|
+
ttl,
|
|
79
|
+
cacheInvalidatedAt
|
|
80
|
+
]);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (!queryPromise || ttl <= 0) return;
|
|
83
|
+
const entry = getCacheEntry(cacheKey);
|
|
84
|
+
if (!entry) return;
|
|
85
|
+
const timeUntilExpiry = entry.expiresAt - Date.now();
|
|
86
|
+
const timer = setTimeout(() => {
|
|
87
|
+
deleteCacheEntry(cacheKey);
|
|
88
|
+
setCacheInvalidatedAt(Date.now());
|
|
89
|
+
}, Math.max(0, timeUntilExpiry));
|
|
90
|
+
return () => clearTimeout(timer);
|
|
91
|
+
}, [
|
|
92
|
+
cacheKey,
|
|
93
|
+
queryPromise,
|
|
94
|
+
ttl
|
|
90
95
|
]);
|
|
91
96
|
let resolvedQuery;
|
|
92
97
|
if (query) if (typeof query === "function") {
|
|
@@ -96,11 +101,6 @@ function useAgent(options) {
|
|
|
96
101
|
resolvedQuery = queryResult;
|
|
97
102
|
}
|
|
98
103
|
} else resolvedQuery = query;
|
|
99
|
-
useEffect(() => {
|
|
100
|
-
return () => {
|
|
101
|
-
if (queryPromise) decrementCacheEntry(cacheKey);
|
|
102
|
-
};
|
|
103
|
-
}, [cacheKey, queryPromise]);
|
|
104
104
|
const agent = usePartySocket({
|
|
105
105
|
party: agentNamespace,
|
|
106
106
|
prefix: "agents",
|
|
@@ -185,5 +185,5 @@ function useAgent(options) {
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
//#endregion
|
|
188
|
-
export { useAgent };
|
|
188
|
+
export { _testUtils, useAgent };
|
|
189
189
|
//# sourceMappingURL=react.js.map
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","names":["resolvedQuery: QueryObject | undefined","parsedMessage: Record<string, unknown>","request: RPCRequest"],"sources":["../src/react.tsx"],"sourcesContent":["import type { PartySocket } from \"partysocket\";\nimport { usePartySocket } from \"partysocket/react\";\nimport { useCallback, useRef, use, useMemo, useEffect } from \"react\";\nimport type { Agent, MCPServersState, RPCRequest, RPCResponse } from \"./\";\nimport type { StreamOptions } from \"./client\";\nimport type { Method, RPCMethod } from \"./serializable\";\nimport { MessageType } from \"./ai-types\";\n\n/**\n * Convert a camelCase string to a kebab-case string\n * @param str The string to convert\n * @returns The kebab-case string\n */\nfunction camelCaseToKebabCase(str: string): string {\n // If string is all uppercase, convert to lowercase\n if (str === str.toUpperCase() && str !== str.toLowerCase()) {\n return str.toLowerCase().replace(/_/g, \"-\");\n }\n\n // Otherwise handle camelCase to kebab-case\n let kebabified = str.replace(\n /[A-Z]/g,\n (letter) => `-${letter.toLowerCase()}`\n );\n kebabified = kebabified.startsWith(\"-\") ? kebabified.slice(1) : kebabified;\n // Convert any remaining underscores to hyphens and remove trailing -'s\n return kebabified.replace(/_/g, \"-\").replace(/-$/, \"\");\n}\n\ntype QueryObject = Record<string, string | null>;\n\nconst queryCache = new Map<\n unknown[],\n {\n promise: Promise<QueryObject>;\n refCount: number;\n expiresAt: number;\n cacheTtl?: number;\n }\n>();\n\nfunction arraysEqual(a: unknown[], b: unknown[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n}\n\nfunction findCacheEntry(\n targetKey: unknown[]\n): Promise<QueryObject> | undefined {\n for (const [existingKey, entry] of queryCache.entries()) {\n if (arraysEqual(existingKey, targetKey)) {\n // Check if entry has expired\n if (Date.now() > entry.expiresAt) {\n queryCache.delete(existingKey);\n return undefined;\n }\n entry.refCount++;\n return entry.promise;\n }\n }\n return undefined;\n}\n\nfunction setCacheEntry(\n key: unknown[],\n value: Promise<QueryObject>,\n cacheTtl?: number\n): void {\n // Remove any existing entry with matching members\n for (const [existingKey] of queryCache.entries()) {\n if (arraysEqual(existingKey, key)) {\n queryCache.delete(existingKey);\n break;\n }\n }\n\n const expiresAt = cacheTtl\n ? Date.now() + cacheTtl\n : Date.now() + 5 * 60 * 1000; // Default 5 minutes\n queryCache.set(key, { promise: value, refCount: 1, expiresAt, cacheTtl });\n}\n\nfunction decrementCacheEntry(targetKey: unknown[]): boolean {\n for (const [existingKey, entry] of queryCache.entries()) {\n if (arraysEqual(existingKey, targetKey)) {\n entry.refCount--;\n if (entry.refCount <= 0) {\n queryCache.delete(existingKey);\n }\n return true;\n }\n }\n return false;\n}\n\nfunction createCacheKey(\n agentNamespace: string,\n name: string | undefined,\n deps: unknown[]\n): unknown[] {\n return [agentNamespace, name || \"default\", ...deps];\n}\n\n/**\n * Options for the useAgent hook\n * @template State Type of the Agent's state\n */\nexport type UseAgentOptions<State = unknown> = Omit<\n Parameters<typeof usePartySocket>[0],\n \"party\" | \"room\" | \"query\"\n> & {\n /** Name of the agent to connect to */\n agent: string;\n /** Name of the specific Agent instance */\n name?: string;\n /** Query parameters - can be static object or async function */\n query?: QueryObject | (() => Promise<QueryObject>);\n /** Dependencies for async query caching */\n queryDeps?: unknown[];\n /** Cache TTL in milliseconds for auth tokens/time-sensitive data */\n cacheTtl?: number;\n /** Called when the Agent's state is updated */\n onStateUpdate?: (state: State, source: \"server\" | \"client\") => void;\n /** Called when MCP server state is updated */\n onMcpUpdate?: (mcpServers: MCPServersState) => void;\n};\n\ntype AllOptional<T> = T extends [infer A, ...infer R]\n ? undefined extends A\n ? AllOptional<R>\n : false\n : true; // no params means optional by default\n\ntype RPCMethods<T> = {\n [K in keyof T as T[K] extends RPCMethod<T[K]> ? K : never]: RPCMethod<T[K]>;\n};\n\ntype OptionalParametersMethod<T extends RPCMethod> =\n AllOptional<Parameters<T>> extends true ? T : never;\n\n// all methods of the Agent, excluding the ones that are declared in the base Agent class\n// biome-ignore lint: suppressions/parse\ntype AgentMethods<T> = Omit<RPCMethods<T>, keyof Agent<any, any>>;\n\ntype OptionalAgentMethods<T> = {\n [K in keyof AgentMethods<T> as AgentMethods<T>[K] extends OptionalParametersMethod<\n AgentMethods<T>[K]\n >\n ? K\n : never]: OptionalParametersMethod<AgentMethods<T>[K]>;\n};\n\ntype RequiredAgentMethods<T> = Omit<\n AgentMethods<T>,\n keyof OptionalAgentMethods<T>\n>;\n\ntype AgentPromiseReturnType<T, K extends keyof AgentMethods<T>> =\n // biome-ignore lint: suppressions/parse\n ReturnType<AgentMethods<T>[K]> extends Promise<any>\n ? ReturnType<AgentMethods<T>[K]>\n : Promise<ReturnType<AgentMethods<T>[K]>>;\n\ntype OptionalArgsAgentMethodCall<AgentT> = <\n K extends keyof OptionalAgentMethods<AgentT>\n>(\n method: K,\n args?: Parameters<OptionalAgentMethods<AgentT>[K]>,\n streamOptions?: StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype RequiredArgsAgentMethodCall<AgentT> = <\n K extends keyof RequiredAgentMethods<AgentT>\n>(\n method: K,\n args: Parameters<RequiredAgentMethods<AgentT>[K]>,\n streamOptions?: StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype AgentMethodCall<AgentT> = OptionalArgsAgentMethodCall<AgentT> &\n RequiredArgsAgentMethodCall<AgentT>;\n\ntype UntypedAgentMethodCall = <T = unknown>(\n method: string,\n args?: unknown[],\n streamOptions?: StreamOptions\n) => Promise<T>;\n\ntype AgentStub<T> = {\n [K in keyof AgentMethods<T>]: (\n ...args: Parameters<AgentMethods<T>[K]>\n ) => AgentPromiseReturnType<AgentMethods<T>, K>;\n};\n\n// we neet to use Method instead of RPCMethod here for retro-compatibility\ntype UntypedAgentStub = Record<string, Method>;\n\n/**\n * React hook for connecting to an Agent\n */\nexport function useAgent<State = unknown>(\n options: UseAgentOptions<State>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall;\n stub: UntypedAgentStub;\n};\nexport function useAgent<\n AgentT extends {\n get state(): State;\n },\n State\n>(\n options: UseAgentOptions<State>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: AgentMethodCall<AgentT>;\n stub: AgentStub<AgentT>;\n};\nexport function useAgent<State>(\n options: UseAgentOptions<unknown>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall | AgentMethodCall<unknown>;\n stub: UntypedAgentStub;\n} {\n const agentNamespace = camelCaseToKebabCase(options.agent);\n const { query, queryDeps, cacheTtl, ...restOptions } = options;\n\n // Keep track of pending RPC calls\n const pendingCallsRef = useRef(\n new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n stream?: StreamOptions;\n }\n >()\n );\n\n // Handle both sync and async query patterns\n const cacheKey = useMemo(() => {\n const deps = queryDeps || [];\n return createCacheKey(agentNamespace, options.name, deps);\n }, [agentNamespace, options.name, queryDeps]);\n\n const queryPromise = useMemo(() => {\n if (!query || typeof query !== \"function\") {\n return null;\n }\n\n const existingPromise = findCacheEntry(cacheKey);\n if (existingPromise) {\n return existingPromise;\n }\n\n const promise = query().catch((error) => {\n console.error(\n `[useAgent] Query failed for agent \"${options.agent}\":`,\n error\n );\n decrementCacheEntry(cacheKey); // Remove failed promise from cache\n throw error; // Re-throw for Suspense error boundary\n });\n\n setCacheEntry(cacheKey, promise, cacheTtl);\n\n return promise;\n }, [cacheKey, query, options.agent, cacheTtl]);\n\n let resolvedQuery: QueryObject | undefined;\n\n if (query) {\n if (typeof query === \"function\") {\n // Use React's use() to resolve the promise\n const queryResult = use(queryPromise!);\n\n // Check for non-primitive values and warn\n if (queryResult) {\n for (const [key, value] of Object.entries(queryResult)) {\n if (\n value !== null &&\n value !== undefined &&\n typeof value !== \"string\" &&\n typeof value !== \"number\" &&\n typeof value !== \"boolean\"\n ) {\n console.warn(\n `[useAgent] Query parameter \"${key}\" is an object and will be converted to \"[object Object]\". ` +\n \"Query parameters should be string, number, boolean, or null.\"\n );\n }\n }\n resolvedQuery = queryResult;\n }\n } else {\n // Sync query - use directly\n resolvedQuery = query;\n }\n }\n\n // Cleanup cache on unmount\n useEffect(() => {\n return () => {\n if (queryPromise) {\n decrementCacheEntry(cacheKey);\n }\n };\n }, [cacheKey, queryPromise]);\n\n const agent = usePartySocket({\n party: agentNamespace,\n prefix: \"agents\",\n room: options.name || \"default\",\n query: resolvedQuery,\n ...restOptions,\n onMessage: (message) => {\n if (typeof message.data === \"string\") {\n let parsedMessage: Record<string, unknown>;\n try {\n parsedMessage = JSON.parse(message.data);\n } catch (_error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return options.onMessage?.(message);\n }\n if (parsedMessage.type === MessageType.CF_AGENT_STATE) {\n options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === MessageType.CF_AGENT_MCP_SERVERS) {\n options.onMcpUpdate?.(parsedMessage.mcp as MCPServersState);\n return;\n }\n if (parsedMessage.type === MessageType.RPC) {\n const response = parsedMessage as RPCResponse;\n const pending = pendingCallsRef.current.get(response.id);\n if (!pending) return;\n\n if (!response.success) {\n pending.reject(new Error(response.error));\n pendingCallsRef.current.delete(response.id);\n pending.stream?.onError?.(response.error);\n return;\n }\n\n // Handle streaming responses\n if (\"done\" in response) {\n if (response.done) {\n pending.resolve(response.result);\n pendingCallsRef.current.delete(response.id);\n pending.stream?.onDone?.(response.result);\n } else {\n pending.stream?.onChunk?.(response.result);\n }\n } else {\n // Non-streaming response\n pending.resolve(response.result);\n pendingCallsRef.current.delete(response.id);\n }\n return;\n }\n }\n options.onMessage?.(message);\n }\n }) as PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall;\n stub: UntypedAgentStub;\n };\n // Create the call method\n const call = useCallback(\n <T = unknown,>(\n method: string,\n args: unknown[] = [],\n streamOptions?: StreamOptions\n ): Promise<T> => {\n return new Promise((resolve, reject) => {\n const id = Math.random().toString(36).slice(2);\n pendingCallsRef.current.set(id, {\n reject,\n resolve: resolve as (value: unknown) => void,\n stream: streamOptions\n });\n\n const request: RPCRequest = {\n args,\n id,\n method,\n type: MessageType.RPC\n };\n\n agent.send(JSON.stringify(request));\n });\n },\n [agent]\n );\n\n agent.setState = (state: State) => {\n agent.send(JSON.stringify({ state, type: MessageType.CF_AGENT_STATE }));\n options.onStateUpdate?.(state, \"client\");\n };\n\n agent.call = call;\n agent.agent = agentNamespace;\n agent.name = options.name || \"default\";\n // biome-ignore lint: suppressions/parse\n agent.stub = new Proxy<any>(\n {},\n {\n get: (_target, method) => {\n return (...args: unknown[]) => {\n return call(method as string, args);\n };\n }\n }\n );\n\n // warn if agent isn't in lowercase\n if (agent.agent !== agent.agent.toLowerCase()) {\n console.warn(\n `Agent name: ${agent.agent} should probably be in lowercase. Received: ${agent.agent}`\n );\n }\n\n return agent;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.js","names":["entry: CacheEntry","resolvedQuery: QueryObject | undefined","parsedMessage: Record<string, unknown>","request: RPCRequest"],"sources":["../src/react.tsx"],"sourcesContent":["import type { PartySocket } from \"partysocket\";\nimport { usePartySocket } from \"partysocket/react\";\nimport { useCallback, useRef, use, useMemo, useState, useEffect } from \"react\";\nimport type { Agent, MCPServersState, RPCRequest, RPCResponse } from \"./\";\nimport type { StreamOptions } from \"./client\";\nimport type { Method, RPCMethod } from \"./serializable\";\nimport { MessageType } from \"./ai-types\";\n\n/**\n * Convert a camelCase string to a kebab-case string\n * @param str The string to convert\n * @returns The kebab-case string\n */\nfunction camelCaseToKebabCase(str: string): string {\n // If string is all uppercase, convert to lowercase\n if (str === str.toUpperCase() && str !== str.toLowerCase()) {\n return str.toLowerCase().replace(/_/g, \"-\");\n }\n\n // Otherwise handle camelCase to kebab-case\n let kebabified = str.replace(\n /[A-Z]/g,\n (letter) => `-${letter.toLowerCase()}`\n );\n kebabified = kebabified.startsWith(\"-\") ? kebabified.slice(1) : kebabified;\n // Convert any remaining underscores to hyphens and remove trailing -'s\n return kebabified.replace(/_/g, \"-\").replace(/-$/, \"\");\n}\n\ntype QueryObject = Record<string, string | null>;\n\ninterface CacheEntry {\n promise: Promise<QueryObject>;\n expiresAt: number;\n}\n\nconst queryCache = new Map<string, CacheEntry>();\n\nfunction createCacheKey(\n agentNamespace: string,\n name: string | undefined,\n deps: unknown[]\n): string {\n return JSON.stringify([agentNamespace, name || \"default\", ...deps]);\n}\n\nfunction getCacheEntry(key: string): CacheEntry | undefined {\n const entry = queryCache.get(key);\n if (!entry) return undefined;\n\n if (Date.now() >= entry.expiresAt) {\n queryCache.delete(key);\n return undefined;\n }\n\n return entry;\n}\n\nfunction setCacheEntry(\n key: string,\n promise: Promise<QueryObject>,\n cacheTtl: number\n): CacheEntry {\n const entry: CacheEntry = {\n promise,\n expiresAt: Date.now() + cacheTtl\n };\n queryCache.set(key, entry);\n return entry;\n}\n\nfunction deleteCacheEntry(key: string): void {\n queryCache.delete(key);\n}\n\n// Export for testing purposes\nexport const _testUtils = {\n queryCache,\n setCacheEntry,\n getCacheEntry,\n deleteCacheEntry,\n clearCache: () => queryCache.clear()\n};\n\n/**\n * Options for the useAgent hook\n * @template State Type of the Agent's state\n */\nexport type UseAgentOptions<State = unknown> = Omit<\n Parameters<typeof usePartySocket>[0],\n \"party\" | \"room\" | \"query\"\n> & {\n /** Name of the agent to connect to */\n agent: string;\n /** Name of the specific Agent instance */\n name?: string;\n /** Query parameters - can be static object or async function */\n query?: QueryObject | (() => Promise<QueryObject>);\n /** Dependencies for async query caching */\n queryDeps?: unknown[];\n /** Cache TTL in milliseconds for auth tokens/time-sensitive data */\n cacheTtl?: number;\n /** Called when the Agent's state is updated */\n onStateUpdate?: (state: State, source: \"server\" | \"client\") => void;\n /** Called when MCP server state is updated */\n onMcpUpdate?: (mcpServers: MCPServersState) => void;\n};\n\ntype AllOptional<T> = T extends [infer A, ...infer R]\n ? undefined extends A\n ? AllOptional<R>\n : false\n : true; // no params means optional by default\n\ntype RPCMethods<T> = {\n [K in keyof T as T[K] extends RPCMethod<T[K]> ? K : never]: RPCMethod<T[K]>;\n};\n\ntype OptionalParametersMethod<T extends RPCMethod> =\n AllOptional<Parameters<T>> extends true ? T : never;\n\n// all methods of the Agent, excluding the ones that are declared in the base Agent class\n// biome-ignore lint: suppressions/parse\ntype AgentMethods<T> = Omit<RPCMethods<T>, keyof Agent<any, any>>;\n\ntype OptionalAgentMethods<T> = {\n [K in keyof AgentMethods<T> as AgentMethods<T>[K] extends OptionalParametersMethod<\n AgentMethods<T>[K]\n >\n ? K\n : never]: OptionalParametersMethod<AgentMethods<T>[K]>;\n};\n\ntype RequiredAgentMethods<T> = Omit<\n AgentMethods<T>,\n keyof OptionalAgentMethods<T>\n>;\n\ntype AgentPromiseReturnType<T, K extends keyof AgentMethods<T>> =\n // biome-ignore lint: suppressions/parse\n ReturnType<AgentMethods<T>[K]> extends Promise<any>\n ? ReturnType<AgentMethods<T>[K]>\n : Promise<ReturnType<AgentMethods<T>[K]>>;\n\ntype OptionalArgsAgentMethodCall<AgentT> = <\n K extends keyof OptionalAgentMethods<AgentT>\n>(\n method: K,\n args?: Parameters<OptionalAgentMethods<AgentT>[K]>,\n streamOptions?: StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype RequiredArgsAgentMethodCall<AgentT> = <\n K extends keyof RequiredAgentMethods<AgentT>\n>(\n method: K,\n args: Parameters<RequiredAgentMethods<AgentT>[K]>,\n streamOptions?: StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype AgentMethodCall<AgentT> = OptionalArgsAgentMethodCall<AgentT> &\n RequiredArgsAgentMethodCall<AgentT>;\n\ntype UntypedAgentMethodCall = <T = unknown>(\n method: string,\n args?: unknown[],\n streamOptions?: StreamOptions\n) => Promise<T>;\n\ntype AgentStub<T> = {\n [K in keyof AgentMethods<T>]: (\n ...args: Parameters<AgentMethods<T>[K]>\n ) => AgentPromiseReturnType<AgentMethods<T>, K>;\n};\n\n// we neet to use Method instead of RPCMethod here for retro-compatibility\ntype UntypedAgentStub = Record<string, Method>;\n\n/**\n * React hook for connecting to an Agent\n */\nexport function useAgent<State = unknown>(\n options: UseAgentOptions<State>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall;\n stub: UntypedAgentStub;\n};\nexport function useAgent<\n AgentT extends {\n get state(): State;\n },\n State\n>(\n options: UseAgentOptions<State>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: AgentMethodCall<AgentT>;\n stub: AgentStub<AgentT>;\n};\nexport function useAgent<State>(\n options: UseAgentOptions<unknown>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall | AgentMethodCall<unknown>;\n stub: UntypedAgentStub;\n} {\n const agentNamespace = camelCaseToKebabCase(options.agent);\n const { query, queryDeps, cacheTtl, ...restOptions } = options;\n\n // Keep track of pending RPC calls\n const pendingCallsRef = useRef(\n new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n stream?: StreamOptions;\n }\n >()\n );\n\n const cacheKey = useMemo(\n () => createCacheKey(agentNamespace, options.name, queryDeps || []),\n [agentNamespace, options.name, queryDeps]\n );\n\n const ttl = cacheTtl ?? 5 * 60 * 1000;\n\n // Track cache invalidation to force re-render when TTL expires\n const [cacheInvalidatedAt, setCacheInvalidatedAt] = useState<number>(0);\n\n // Get or create the query promise\n // biome-ignore lint/correctness/useExhaustiveDependencies: cacheInvalidatedAt intentionally forces re-evaluation when TTL expires\n const queryPromise = useMemo(() => {\n if (!query || typeof query !== \"function\") {\n return null;\n }\n\n // Always check cache first to deduplicate concurrent requests\n const cached = getCacheEntry(cacheKey);\n if (cached) {\n return cached.promise;\n }\n\n // Create new promise\n const promise = query().catch((error) => {\n console.error(\n `[useAgent] Query failed for agent \"${options.agent}\":`,\n error\n );\n deleteCacheEntry(cacheKey);\n throw error;\n });\n\n // Always cache to deduplicate concurrent requests\n setCacheEntry(cacheKey, promise, ttl);\n\n return promise;\n }, [cacheKey, query, options.agent, ttl, cacheInvalidatedAt]);\n\n // Schedule cache invalidation when TTL expires\n useEffect(() => {\n if (!queryPromise || ttl <= 0) return;\n\n const entry = getCacheEntry(cacheKey);\n if (!entry) return;\n\n const timeUntilExpiry = entry.expiresAt - Date.now();\n\n // Always set a timer (with min 0ms) to ensure cleanup function is returned\n const timer = setTimeout(\n () => {\n deleteCacheEntry(cacheKey);\n setCacheInvalidatedAt(Date.now());\n },\n Math.max(0, timeUntilExpiry)\n );\n\n return () => clearTimeout(timer);\n }, [cacheKey, queryPromise, ttl]);\n\n let resolvedQuery: QueryObject | undefined;\n\n if (query) {\n if (typeof query === \"function\") {\n // Use React's use() to resolve the promise\n const queryResult = use(queryPromise!);\n\n // Check for non-primitive values and warn\n if (queryResult) {\n for (const [key, value] of Object.entries(queryResult)) {\n if (\n value !== null &&\n value !== undefined &&\n typeof value !== \"string\" &&\n typeof value !== \"number\" &&\n typeof value !== \"boolean\"\n ) {\n console.warn(\n `[useAgent] Query parameter \"${key}\" is an object and will be converted to \"[object Object]\". ` +\n \"Query parameters should be string, number, boolean, or null.\"\n );\n }\n }\n resolvedQuery = queryResult;\n }\n } else {\n // Sync query - use directly\n resolvedQuery = query;\n }\n }\n\n const agent = usePartySocket({\n party: agentNamespace,\n prefix: \"agents\",\n room: options.name || \"default\",\n query: resolvedQuery,\n ...restOptions,\n onMessage: (message) => {\n if (typeof message.data === \"string\") {\n let parsedMessage: Record<string, unknown>;\n try {\n parsedMessage = JSON.parse(message.data);\n } catch (_error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return options.onMessage?.(message);\n }\n if (parsedMessage.type === MessageType.CF_AGENT_STATE) {\n options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === MessageType.CF_AGENT_MCP_SERVERS) {\n options.onMcpUpdate?.(parsedMessage.mcp as MCPServersState);\n return;\n }\n if (parsedMessage.type === MessageType.RPC) {\n const response = parsedMessage as RPCResponse;\n const pending = pendingCallsRef.current.get(response.id);\n if (!pending) return;\n\n if (!response.success) {\n pending.reject(new Error(response.error));\n pendingCallsRef.current.delete(response.id);\n pending.stream?.onError?.(response.error);\n return;\n }\n\n // Handle streaming responses\n if (\"done\" in response) {\n if (response.done) {\n pending.resolve(response.result);\n pendingCallsRef.current.delete(response.id);\n pending.stream?.onDone?.(response.result);\n } else {\n pending.stream?.onChunk?.(response.result);\n }\n } else {\n // Non-streaming response\n pending.resolve(response.result);\n pendingCallsRef.current.delete(response.id);\n }\n return;\n }\n }\n options.onMessage?.(message);\n }\n }) as PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall;\n stub: UntypedAgentStub;\n };\n // Create the call method\n const call = useCallback(\n <T = unknown,>(\n method: string,\n args: unknown[] = [],\n streamOptions?: StreamOptions\n ): Promise<T> => {\n return new Promise((resolve, reject) => {\n const id = Math.random().toString(36).slice(2);\n pendingCallsRef.current.set(id, {\n reject,\n resolve: resolve as (value: unknown) => void,\n stream: streamOptions\n });\n\n const request: RPCRequest = {\n args,\n id,\n method,\n type: MessageType.RPC\n };\n\n agent.send(JSON.stringify(request));\n });\n },\n [agent]\n );\n\n agent.setState = (state: State) => {\n agent.send(JSON.stringify({ state, type: MessageType.CF_AGENT_STATE }));\n options.onStateUpdate?.(state, \"client\");\n };\n\n agent.call = call;\n agent.agent = agentNamespace;\n agent.name = options.name || \"default\";\n // biome-ignore lint: suppressions/parse\n agent.stub = new Proxy<any>(\n {},\n {\n get: (_target, method) => {\n return (...args: unknown[]) => {\n return call(method as string, args);\n };\n }\n }\n );\n\n // warn if agent isn't in lowercase\n if (agent.agent !== agent.agent.toLowerCase()) {\n console.warn(\n `Agent name: ${agent.agent} should probably be in lowercase. Received: ${agent.agent}`\n );\n }\n\n return agent;\n}\n"],"mappings":"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"}
|
package/dist/schedule.d.ts
CHANGED
|
@@ -23,46 +23,19 @@ declare const scheduleSchema: z.ZodObject<
|
|
|
23
23
|
when: z.ZodObject<
|
|
24
24
|
{
|
|
25
25
|
cron: z.ZodOptional<z.ZodString>;
|
|
26
|
-
date: z.ZodOptional<z.
|
|
26
|
+
date: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
27
27
|
delayInSeconds: z.ZodOptional<z.ZodNumber>;
|
|
28
|
-
type: z.ZodEnum<
|
|
28
|
+
type: z.ZodEnum<{
|
|
29
|
+
cron: "cron";
|
|
30
|
+
scheduled: "scheduled";
|
|
31
|
+
delayed: "delayed";
|
|
32
|
+
"no-schedule": "no-schedule";
|
|
33
|
+
}>;
|
|
29
34
|
},
|
|
30
|
-
|
|
31
|
-
z.ZodTypeAny,
|
|
32
|
-
{
|
|
33
|
-
type: "cron" | "scheduled" | "delayed" | "no-schedule";
|
|
34
|
-
date?: Date | undefined;
|
|
35
|
-
cron?: string | undefined;
|
|
36
|
-
delayInSeconds?: number | undefined;
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
type: "cron" | "scheduled" | "delayed" | "no-schedule";
|
|
40
|
-
date?: Date | undefined;
|
|
41
|
-
cron?: string | undefined;
|
|
42
|
-
delayInSeconds?: number | undefined;
|
|
43
|
-
}
|
|
35
|
+
z.core.$strip
|
|
44
36
|
>;
|
|
45
37
|
},
|
|
46
|
-
|
|
47
|
-
z.ZodTypeAny,
|
|
48
|
-
{
|
|
49
|
-
description: string;
|
|
50
|
-
when: {
|
|
51
|
-
type: "cron" | "scheduled" | "delayed" | "no-schedule";
|
|
52
|
-
date?: Date | undefined;
|
|
53
|
-
cron?: string | undefined;
|
|
54
|
-
delayInSeconds?: number | undefined;
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
description: string;
|
|
59
|
-
when: {
|
|
60
|
-
type: "cron" | "scheduled" | "delayed" | "no-schedule";
|
|
61
|
-
date?: Date | undefined;
|
|
62
|
-
cron?: string | undefined;
|
|
63
|
-
delayInSeconds?: number | undefined;
|
|
64
|
-
};
|
|
65
|
-
}
|
|
38
|
+
z.core.$strip
|
|
66
39
|
>;
|
|
67
40
|
/**
|
|
68
41
|
* The type for the schedule prompt
|
|
@@ -78,46 +51,19 @@ declare const unstable_scheduleSchema: z.ZodObject<
|
|
|
78
51
|
when: z.ZodObject<
|
|
79
52
|
{
|
|
80
53
|
cron: z.ZodOptional<z.ZodString>;
|
|
81
|
-
date: z.ZodOptional<z.
|
|
54
|
+
date: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
82
55
|
delayInSeconds: z.ZodOptional<z.ZodNumber>;
|
|
83
|
-
type: z.ZodEnum<
|
|
56
|
+
type: z.ZodEnum<{
|
|
57
|
+
cron: "cron";
|
|
58
|
+
scheduled: "scheduled";
|
|
59
|
+
delayed: "delayed";
|
|
60
|
+
"no-schedule": "no-schedule";
|
|
61
|
+
}>;
|
|
84
62
|
},
|
|
85
|
-
|
|
86
|
-
z.ZodTypeAny,
|
|
87
|
-
{
|
|
88
|
-
type: "cron" | "scheduled" | "delayed" | "no-schedule";
|
|
89
|
-
date?: Date | undefined;
|
|
90
|
-
cron?: string | undefined;
|
|
91
|
-
delayInSeconds?: number | undefined;
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
type: "cron" | "scheduled" | "delayed" | "no-schedule";
|
|
95
|
-
date?: Date | undefined;
|
|
96
|
-
cron?: string | undefined;
|
|
97
|
-
delayInSeconds?: number | undefined;
|
|
98
|
-
}
|
|
63
|
+
z.core.$strip
|
|
99
64
|
>;
|
|
100
65
|
},
|
|
101
|
-
|
|
102
|
-
z.ZodTypeAny,
|
|
103
|
-
{
|
|
104
|
-
description: string;
|
|
105
|
-
when: {
|
|
106
|
-
type: "cron" | "scheduled" | "delayed" | "no-schedule";
|
|
107
|
-
date?: Date | undefined;
|
|
108
|
-
cron?: string | undefined;
|
|
109
|
-
delayInSeconds?: number | undefined;
|
|
110
|
-
};
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
description: string;
|
|
114
|
-
when: {
|
|
115
|
-
type: "cron" | "scheduled" | "delayed" | "no-schedule";
|
|
116
|
-
date?: Date | undefined;
|
|
117
|
-
cron?: string | undefined;
|
|
118
|
-
delayInSeconds?: number | undefined;
|
|
119
|
-
};
|
|
120
|
-
}
|
|
66
|
+
z.core.$strip
|
|
121
67
|
>;
|
|
122
68
|
//#endregion
|
|
123
69
|
export {
|
package/dist/serializable.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import {
|
|
3
|
-
import { r as
|
|
4
|
-
import { t as
|
|
5
|
-
import {
|
|
1
|
+
import { t as agentContext } from "./context-BkKbAa1R.js";
|
|
2
|
+
import { t as MessageType } from "./ai-types-DEtF_8Km.js";
|
|
3
|
+
import { r as camelCaseToKebabCase } from "./client-DjTPRM8-.js";
|
|
4
|
+
import { i as DisposableStore, r as MCPConnectionState, t as MCPClientManager } from "./client-QZa2Rq0l.js";
|
|
5
|
+
import { t as DurableObjectOAuthClientProvider } from "./do-oauth-client-provider-B1fVIshX.js";
|
|
6
6
|
import { parseCronExpression } from "cron-schedule";
|
|
7
7
|
import { nanoid } from "nanoid";
|
|
8
8
|
import { EmailMessage } from "cloudflare:email";
|
|
@@ -72,7 +72,6 @@ function getNextCronTime(cron) {
|
|
|
72
72
|
const STATE_ROW_ID = "cf_state_row_id";
|
|
73
73
|
const STATE_WAS_CHANGED = "cf_state_was_changed";
|
|
74
74
|
const DEFAULT_STATE = {};
|
|
75
|
-
const agentContext = new AsyncLocalStorage();
|
|
76
75
|
function getCurrentAgent() {
|
|
77
76
|
const store = agentContext.getStore();
|
|
78
77
|
if (!store) return {
|
|
@@ -717,10 +716,7 @@ var Agent = class Agent extends Server {
|
|
|
717
716
|
const result = this.sql`
|
|
718
717
|
SELECT * FROM cf_agents_schedules WHERE id = ${id}
|
|
719
718
|
`;
|
|
720
|
-
if (!result)
|
|
721
|
-
console.error(`schedule ${id} not found`);
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
719
|
+
if (!result || result.length === 0) return;
|
|
724
720
|
return {
|
|
725
721
|
...result[0],
|
|
726
722
|
payload: JSON.parse(result[0].payload)
|
|
@@ -757,11 +753,12 @@ var Agent = class Agent extends Server {
|
|
|
757
753
|
/**
|
|
758
754
|
* Cancel a scheduled task
|
|
759
755
|
* @param id ID of the task to cancel
|
|
760
|
-
* @returns true if the task was cancelled, false
|
|
756
|
+
* @returns true if the task was cancelled, false if the task was not found
|
|
761
757
|
*/
|
|
762
758
|
async cancelSchedule(id) {
|
|
763
759
|
const schedule = await this.getSchedule(id);
|
|
764
|
-
if (schedule)
|
|
760
|
+
if (!schedule) return false;
|
|
761
|
+
this.observability?.emit({
|
|
765
762
|
displayMessage: `Schedule ${id} cancelled`,
|
|
766
763
|
id: nanoid(),
|
|
767
764
|
payload: {
|
|
@@ -827,7 +824,8 @@ var Agent = class Agent extends Server {
|
|
|
827
824
|
* @param callbackHost Base host for the agent, used for the redirect URI. If not provided, will be derived from the current request.
|
|
828
825
|
* @param agentsPrefix agents routing prefix if not using `agents`
|
|
829
826
|
* @param options MCP client and transport options
|
|
830
|
-
* @returns authUrl
|
|
827
|
+
* @returns Server id and state - either "authenticating" with authUrl, or "ready"
|
|
828
|
+
* @throws If connection or discovery fails
|
|
831
829
|
*/
|
|
832
830
|
async addMcpServer(serverName, url, callbackHost, agentsPrefix = "agents", options) {
|
|
833
831
|
let resolvedCallbackHost = callbackHost;
|
|
@@ -863,14 +861,21 @@ var Agent = class Agent extends Server {
|
|
|
863
861
|
}
|
|
864
862
|
});
|
|
865
863
|
const result = await this.mcp.connectToServer(id);
|
|
864
|
+
if (result.state === MCPConnectionState.FAILED) throw new Error(`Failed to connect to MCP server at ${url}: ${result.error}`);
|
|
865
|
+
if (result.state === MCPConnectionState.AUTHENTICATING) return {
|
|
866
|
+
id,
|
|
867
|
+
state: result.state,
|
|
868
|
+
authUrl: result.authUrl
|
|
869
|
+
};
|
|
870
|
+
const discoverResult = await this.mcp.discoverIfConnected(id);
|
|
871
|
+
if (discoverResult && !discoverResult.success) throw new Error(`Failed to discover MCP server capabilities: ${discoverResult.error}`);
|
|
866
872
|
return {
|
|
867
873
|
id,
|
|
868
|
-
|
|
874
|
+
state: MCPConnectionState.READY
|
|
869
875
|
};
|
|
870
876
|
}
|
|
871
877
|
async removeMcpServer(id) {
|
|
872
|
-
|
|
873
|
-
this.mcp.removeServer(id);
|
|
878
|
+
await this.mcp.removeServer(id);
|
|
874
879
|
}
|
|
875
880
|
getMcpServers() {
|
|
876
881
|
const mcpState = {
|
|
@@ -917,14 +922,10 @@ var Agent = class Agent extends Server {
|
|
|
917
922
|
async handleMcpOAuthCallback(request) {
|
|
918
923
|
if (!this.mcp.isCallbackRequest(request)) return null;
|
|
919
924
|
const result = await this.mcp.handleCallbackRequest(request);
|
|
920
|
-
if (result.authSuccess) {
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
}).finally(() => {
|
|
925
|
-
this.broadcastMcpServers();
|
|
926
|
-
});
|
|
927
|
-
}
|
|
925
|
+
if (result.authSuccess) this.mcp.establishConnection(result.serverId).catch((error) => {
|
|
926
|
+
console.error("[Agent handleMcpOAuthCallback] Connection establishment failed:", error);
|
|
927
|
+
});
|
|
928
|
+
this.broadcastMcpServers();
|
|
928
929
|
return this.handleOAuthCallbackResponse(result, request);
|
|
929
930
|
}
|
|
930
931
|
/**
|
|
@@ -1177,4 +1178,4 @@ var StreamingResponse = class {
|
|
|
1177
1178
|
|
|
1178
1179
|
//#endregion
|
|
1179
1180
|
export { createCatchAllEmailResolver as a, getCurrentAgent as c, unstable_callable as d, genericObservability as f, createAddressBasedEmailResolver as i, routeAgentEmail as l, StreamingResponse as n, createHeaderBasedEmailResolver as o, callable as r, getAgentByName as s, Agent as t, routeAgentRequest as u };
|
|
1180
|
-
//# sourceMappingURL=src-
|
|
1181
|
+
//# sourceMappingURL=src-BZDh910Z.js.map
|