@ariaflowagents/cf-agent 0.7.0 → 0.9.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/README.md +436 -135
- package/dist/AriaFlowAgent.d.ts +109 -0
- package/dist/AriaFlowAgent.d.ts.map +1 -0
- package/dist/AriaFlowAgent.js +170 -0
- package/dist/AriaFlowAgent.js.map +1 -0
- package/dist/BridgeSessionStore.d.ts +37 -0
- package/dist/BridgeSessionStore.d.ts.map +1 -0
- package/dist/BridgeSessionStore.js +120 -0
- package/dist/BridgeSessionStore.js.map +1 -0
- package/dist/OrchestrationStore.d.ts +25 -0
- package/dist/OrchestrationStore.d.ts.map +1 -0
- package/dist/OrchestrationStore.js +63 -0
- package/dist/OrchestrationStore.js.map +1 -0
- package/dist/StreamAdapter.d.ts +19 -0
- package/dist/StreamAdapter.d.ts.map +1 -0
- package/dist/StreamAdapter.js +205 -0
- package/dist/StreamAdapter.js.map +1 -0
- package/dist/index.d.ts +33 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -27
- package/dist/AriaFlowChatAgent.d.ts +0 -24
- package/dist/AriaFlowChatAgent.d.ts.map +0 -1
- package/dist/AriaFlowChatAgent.js +0 -153
- package/dist/AriaFlowChatAgent.js.map +0 -1
- package/dist/AriaFlowFlowAgent.d.ts +0 -88
- package/dist/AriaFlowFlowAgent.d.ts.map +0 -1
- package/dist/AriaFlowFlowAgent.js +0 -185
- package/dist/AriaFlowFlowAgent.js.map +0 -1
- package/dist/stores/CloudflareSQLiteStore.d.ts +0 -12
- package/dist/stores/CloudflareSQLiteStore.d.ts.map +0 -1
- package/dist/stores/CloudflareSQLiteStore.js +0 -99
- package/dist/stores/CloudflareSQLiteStore.js.map +0 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AriaFlowAgent -- AriaFlow on Cloudflare Durable Objects.
|
|
3
|
+
*
|
|
4
|
+
* Extends CF's AIChatAgent and works WITH it, not against it:
|
|
5
|
+
*
|
|
6
|
+
* CF owns: messages, persistence, WebSocket, resumability
|
|
7
|
+
* AriaFlow owns: agent orchestration (current agent, working memory,
|
|
8
|
+
* flow state, handoff history, extraction data)
|
|
9
|
+
*
|
|
10
|
+
* On each chat message:
|
|
11
|
+
* 1. CF calls onChatMessage() with this.messages already populated
|
|
12
|
+
* 2. We build a BridgeSessionStore from CF messages + orchestration state
|
|
13
|
+
* 3. AriaFlow Runtime runs the agent pipeline
|
|
14
|
+
* 4. We return an SSE Response in AI SDK format
|
|
15
|
+
* 5. CF's _reply() reads the SSE stream, builds message parts,
|
|
16
|
+
* calls persistMessages(), broadcasts to clients, handles resumability
|
|
17
|
+
*
|
|
18
|
+
* AriaFlow's orchestration state (current agent, working memory, flow state)
|
|
19
|
+
* is stored in a separate lightweight SQLite table via OrchestrationStore.
|
|
20
|
+
*/
|
|
21
|
+
import { AIChatAgent } from '@cloudflare/ai-chat';
|
|
22
|
+
import type { HarnessConfig } from '@ariaflowagents/core';
|
|
23
|
+
import type { StreamTextOnFinishCallback, ToolSet } from 'ai';
|
|
24
|
+
import type { OnChatMessageOptions } from '@cloudflare/ai-chat';
|
|
25
|
+
import type { StreamAdapterConfig } from './types.js';
|
|
26
|
+
/**
|
|
27
|
+
* Abstract base class for running AriaFlow agents on Cloudflare.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* import { AriaFlowAgent } from '@ariaflowagents/cf-agent';
|
|
32
|
+
* import { openai } from '@ai-sdk/openai';
|
|
33
|
+
*
|
|
34
|
+
* class MyAgent extends AriaFlowAgent<Env> {
|
|
35
|
+
* protected getAgents(): HarnessConfig['agents'] {
|
|
36
|
+
* return [{
|
|
37
|
+
* id: 'assistant',
|
|
38
|
+
* name: 'Assistant',
|
|
39
|
+
* type: 'llm',
|
|
40
|
+
* model: openai('gpt-4o', { apiKey: this.env.OPENAI_API_KEY }),
|
|
41
|
+
* prompt: 'You are a helpful assistant.',
|
|
42
|
+
* }];
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* protected getDefaultAgentId() { return 'assistant'; }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare abstract class AriaFlowAgent<Env = any, State = unknown> extends AIChatAgent<Env, State> {
|
|
50
|
+
private runtime;
|
|
51
|
+
/**
|
|
52
|
+
* Required: Define the agents for this runtime.
|
|
53
|
+
*/
|
|
54
|
+
protected abstract getAgents(): HarnessConfig['agents'];
|
|
55
|
+
/**
|
|
56
|
+
* Required: Which agent handles the first message.
|
|
57
|
+
*/
|
|
58
|
+
protected abstract getDefaultAgentId(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Optional: Additional runtime config (hooks, model, processors, etc.).
|
|
61
|
+
* Merged with agents + defaultAgentId + sessionStore.
|
|
62
|
+
*/
|
|
63
|
+
protected getRuntimeConfig(): Partial<HarnessConfig>;
|
|
64
|
+
/**
|
|
65
|
+
* Optional: Configure which AriaFlow events become data parts in the stream.
|
|
66
|
+
*/
|
|
67
|
+
protected getStreamConfig(): Partial<StreamAdapterConfig>;
|
|
68
|
+
/**
|
|
69
|
+
* Get the SQL executor for the Durable Object.
|
|
70
|
+
* CF's AIChatAgent exposes this.sql as a tagged template function.
|
|
71
|
+
*/
|
|
72
|
+
private getSql;
|
|
73
|
+
/**
|
|
74
|
+
* Get the Durable Object ID as the session identifier.
|
|
75
|
+
*/
|
|
76
|
+
private getSessionId;
|
|
77
|
+
/**
|
|
78
|
+
* Called by CF when a chat message arrives.
|
|
79
|
+
*
|
|
80
|
+
* CF has already:
|
|
81
|
+
* 1. Received the WebSocket message from the client
|
|
82
|
+
* 2. Parsed and validated it
|
|
83
|
+
* 3. Persisted the user message to cf_ai_chat_agent_messages
|
|
84
|
+
* 4. Populated this.messages with the full conversation history
|
|
85
|
+
*
|
|
86
|
+
* We:
|
|
87
|
+
* 1. Create a BridgeSessionStore (CF messages + orchestration state)
|
|
88
|
+
* 2. Build and run AriaFlow Runtime
|
|
89
|
+
* 3. Return an SSE Response
|
|
90
|
+
*
|
|
91
|
+
* CF then:
|
|
92
|
+
* 1. Reads the SSE stream via _reply()
|
|
93
|
+
* 2. Builds assistant message parts via applyChunkToParts()
|
|
94
|
+
* 3. Persists the assistant message
|
|
95
|
+
* 4. Broadcasts to all connected clients
|
|
96
|
+
* 5. Handles stream resumability
|
|
97
|
+
*/
|
|
98
|
+
onChatMessage(onFinish: StreamTextOnFinishCallback<ToolSet>, options?: OnChatMessageOptions): Promise<Response>;
|
|
99
|
+
/**
|
|
100
|
+
* Extract the text content of the last user message from CF's messages array.
|
|
101
|
+
*/
|
|
102
|
+
private getLastUserInput;
|
|
103
|
+
/**
|
|
104
|
+
* HTTP endpoint handler.
|
|
105
|
+
* Adds AriaFlow-specific endpoints on top of CF's defaults.
|
|
106
|
+
*/
|
|
107
|
+
onRequest(request: Request): Promise<Response>;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=AriaFlowAgent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AriaFlowAgent.d.ts","sourceRoot":"","sources":["../src/AriaFlowAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,KAAK,EACV,aAAa,EAGd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,0BAA0B,EAAE,OAAO,EAAa,MAAM,IAAI,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,YAAY,CAAC;AAGnE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,8BAAsB,aAAa,CACjC,GAAG,GAAG,GAAG,EACT,KAAK,GAAG,OAAO,CACf,SAAQ,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC;IAC/B,OAAO,CAAC,OAAO,CAAwB;IAEvC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,SAAS,IAAI,aAAa,CAAC,QAAQ,CAAC;IAEvD;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,iBAAiB,IAAI,MAAM;IAE9C;;;OAGG;IACH,SAAS,CAAC,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC;IAIpD;;OAEG;IACH,SAAS,CAAC,eAAe,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIzD;;;OAGG;IACH,OAAO,CAAC,MAAM;IAId;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,aAAa,CACjB,QAAQ,EAAE,0BAA0B,CAAC,OAAO,CAAC,EAC7C,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,QAAQ,CAAC;IA4CpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;OAGG;IACG,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;CAerD"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AriaFlowAgent -- AriaFlow on Cloudflare Durable Objects.
|
|
3
|
+
*
|
|
4
|
+
* Extends CF's AIChatAgent and works WITH it, not against it:
|
|
5
|
+
*
|
|
6
|
+
* CF owns: messages, persistence, WebSocket, resumability
|
|
7
|
+
* AriaFlow owns: agent orchestration (current agent, working memory,
|
|
8
|
+
* flow state, handoff history, extraction data)
|
|
9
|
+
*
|
|
10
|
+
* On each chat message:
|
|
11
|
+
* 1. CF calls onChatMessage() with this.messages already populated
|
|
12
|
+
* 2. We build a BridgeSessionStore from CF messages + orchestration state
|
|
13
|
+
* 3. AriaFlow Runtime runs the agent pipeline
|
|
14
|
+
* 4. We return an SSE Response in AI SDK format
|
|
15
|
+
* 5. CF's _reply() reads the SSE stream, builds message parts,
|
|
16
|
+
* calls persistMessages(), broadcasts to clients, handles resumability
|
|
17
|
+
*
|
|
18
|
+
* AriaFlow's orchestration state (current agent, working memory, flow state)
|
|
19
|
+
* is stored in a separate lightweight SQLite table via OrchestrationStore.
|
|
20
|
+
*/
|
|
21
|
+
import { AIChatAgent } from '@cloudflare/ai-chat';
|
|
22
|
+
import { Runtime } from '@ariaflowagents/core';
|
|
23
|
+
import { BridgeSessionStore } from './BridgeSessionStore.js';
|
|
24
|
+
import { createSSEResponse } from './StreamAdapter.js';
|
|
25
|
+
import { DEFAULT_STREAM_CONFIG } from './types.js';
|
|
26
|
+
/**
|
|
27
|
+
* Abstract base class for running AriaFlow agents on Cloudflare.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* import { AriaFlowAgent } from '@ariaflowagents/cf-agent';
|
|
32
|
+
* import { openai } from '@ai-sdk/openai';
|
|
33
|
+
*
|
|
34
|
+
* class MyAgent extends AriaFlowAgent<Env> {
|
|
35
|
+
* protected getAgents(): HarnessConfig['agents'] {
|
|
36
|
+
* return [{
|
|
37
|
+
* id: 'assistant',
|
|
38
|
+
* name: 'Assistant',
|
|
39
|
+
* type: 'llm',
|
|
40
|
+
* model: openai('gpt-4o', { apiKey: this.env.OPENAI_API_KEY }),
|
|
41
|
+
* prompt: 'You are a helpful assistant.',
|
|
42
|
+
* }];
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* protected getDefaultAgentId() { return 'assistant'; }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export class AriaFlowAgent extends AIChatAgent {
|
|
50
|
+
runtime = null;
|
|
51
|
+
/**
|
|
52
|
+
* Optional: Additional runtime config (hooks, model, processors, etc.).
|
|
53
|
+
* Merged with agents + defaultAgentId + sessionStore.
|
|
54
|
+
*/
|
|
55
|
+
getRuntimeConfig() {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Optional: Configure which AriaFlow events become data parts in the stream.
|
|
60
|
+
*/
|
|
61
|
+
getStreamConfig() {
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the SQL executor for the Durable Object.
|
|
66
|
+
* CF's AIChatAgent exposes this.sql as a tagged template function.
|
|
67
|
+
*/
|
|
68
|
+
getSql() {
|
|
69
|
+
return this.sql.bind(this);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get the Durable Object ID as the session identifier.
|
|
73
|
+
*/
|
|
74
|
+
getSessionId() {
|
|
75
|
+
return this.ctx?.id?.toString() ?? crypto.randomUUID();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Called by CF when a chat message arrives.
|
|
79
|
+
*
|
|
80
|
+
* CF has already:
|
|
81
|
+
* 1. Received the WebSocket message from the client
|
|
82
|
+
* 2. Parsed and validated it
|
|
83
|
+
* 3. Persisted the user message to cf_ai_chat_agent_messages
|
|
84
|
+
* 4. Populated this.messages with the full conversation history
|
|
85
|
+
*
|
|
86
|
+
* We:
|
|
87
|
+
* 1. Create a BridgeSessionStore (CF messages + orchestration state)
|
|
88
|
+
* 2. Build and run AriaFlow Runtime
|
|
89
|
+
* 3. Return an SSE Response
|
|
90
|
+
*
|
|
91
|
+
* CF then:
|
|
92
|
+
* 1. Reads the SSE stream via _reply()
|
|
93
|
+
* 2. Builds assistant message parts via applyChunkToParts()
|
|
94
|
+
* 3. Persists the assistant message
|
|
95
|
+
* 4. Broadcasts to all connected clients
|
|
96
|
+
* 5. Handles stream resumability
|
|
97
|
+
*/
|
|
98
|
+
async onChatMessage(onFinish, options) {
|
|
99
|
+
// Extract the latest user input from CF's messages
|
|
100
|
+
const lastUserMessage = this.getLastUserInput();
|
|
101
|
+
if (!lastUserMessage) {
|
|
102
|
+
return new Response('No user message', { status: 400 });
|
|
103
|
+
}
|
|
104
|
+
const sessionId = this.getSessionId();
|
|
105
|
+
const defaultAgentId = this.getDefaultAgentId();
|
|
106
|
+
// Build session store that bridges CF messages with AriaFlow state
|
|
107
|
+
const sessionStore = new BridgeSessionStore({
|
|
108
|
+
sqlExecutor: this.getSql(),
|
|
109
|
+
cfMessages: this.messages,
|
|
110
|
+
sessionId,
|
|
111
|
+
defaultAgentId,
|
|
112
|
+
});
|
|
113
|
+
// Build runtime (fresh per request to pick up latest config)
|
|
114
|
+
const extraConfig = this.getRuntimeConfig();
|
|
115
|
+
this.runtime = new Runtime({
|
|
116
|
+
...extraConfig,
|
|
117
|
+
agents: this.getAgents(),
|
|
118
|
+
defaultAgentId,
|
|
119
|
+
sessionStore,
|
|
120
|
+
});
|
|
121
|
+
// Run AriaFlow
|
|
122
|
+
const stream = this.runtime.stream({
|
|
123
|
+
input: lastUserMessage,
|
|
124
|
+
sessionId,
|
|
125
|
+
userId: options?.body?.userId,
|
|
126
|
+
abortSignal: options?.abortSignal,
|
|
127
|
+
});
|
|
128
|
+
// Convert to SSE Response that CF's _reply() can parse
|
|
129
|
+
const streamConfig = {
|
|
130
|
+
...DEFAULT_STREAM_CONFIG,
|
|
131
|
+
...this.getStreamConfig(),
|
|
132
|
+
};
|
|
133
|
+
return createSSEResponse(stream, streamConfig);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Extract the text content of the last user message from CF's messages array.
|
|
137
|
+
*/
|
|
138
|
+
getLastUserInput() {
|
|
139
|
+
for (let i = this.messages.length - 1; i >= 0; i--) {
|
|
140
|
+
const msg = this.messages[i];
|
|
141
|
+
if (msg.role !== 'user')
|
|
142
|
+
continue;
|
|
143
|
+
const text = msg.parts
|
|
144
|
+
?.filter((p) => p.type === 'text')
|
|
145
|
+
.map((p) => p.text ?? '')
|
|
146
|
+
.join('');
|
|
147
|
+
if (text?.trim())
|
|
148
|
+
return text;
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* HTTP endpoint handler.
|
|
154
|
+
* Adds AriaFlow-specific endpoints on top of CF's defaults.
|
|
155
|
+
*/
|
|
156
|
+
async onRequest(request) {
|
|
157
|
+
const url = new URL(request.url);
|
|
158
|
+
if (url.pathname.endsWith('/orchestration-state')) {
|
|
159
|
+
const { OrchestrationStore } = await import('./OrchestrationStore.js');
|
|
160
|
+
const store = new OrchestrationStore(this.getSql());
|
|
161
|
+
const state = await store.get();
|
|
162
|
+
return Response.json({
|
|
163
|
+
sessionId: this.getSessionId(),
|
|
164
|
+
state: state ?? null,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return super.onRequest(request);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=AriaFlowAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AriaFlowAgent.js","sourceRoot":"","sources":["../src/AriaFlowAgent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Session, SessionStore } from '@ariaflowagents/core';
|
|
2
|
+
import type { UIMessage } from 'ai';
|
|
3
|
+
/**
|
|
4
|
+
* Bridge SessionStore that splits concerns between CF and AriaFlow.
|
|
5
|
+
*
|
|
6
|
+
* CF owns messages (via AIChatAgent's cf_ai_chat_agent_messages table).
|
|
7
|
+
* AriaFlow owns orchestration state (via OrchestrationStore).
|
|
8
|
+
*
|
|
9
|
+
* On get(): reconstructs a Session by combining CF's messages with
|
|
10
|
+
* AriaFlow's orchestration state.
|
|
11
|
+
*
|
|
12
|
+
* On save(): extracts orchestration state from the Session and saves
|
|
13
|
+
* it. Does NOT save messages -- CF handles that via persistMessages().
|
|
14
|
+
*/
|
|
15
|
+
export declare class BridgeSessionStore implements SessionStore {
|
|
16
|
+
private orchestration;
|
|
17
|
+
private cfMessages;
|
|
18
|
+
private sessionId;
|
|
19
|
+
private defaultAgentId;
|
|
20
|
+
constructor(options: {
|
|
21
|
+
sqlExecutor: (...args: any[]) => any;
|
|
22
|
+
cfMessages: UIMessage[];
|
|
23
|
+
sessionId: string;
|
|
24
|
+
defaultAgentId: string;
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Reconstruct a Session from CF messages + orchestration state.
|
|
28
|
+
*/
|
|
29
|
+
get(id: string): Promise<Session | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Save only orchestration state. CF handles message persistence.
|
|
32
|
+
*/
|
|
33
|
+
save(session: Session): Promise<void>;
|
|
34
|
+
delete(id: string): Promise<void>;
|
|
35
|
+
list(): Promise<Session[]>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=BridgeSessionStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BridgeSessionStore.d.ts","sourceRoot":"","sources":["../src/BridgeSessionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAIpC;;;;;;;;;;;GAWG;AACH,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,EAAE;QACnB,WAAW,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;QACrC,UAAU,EAAE,SAAS,EAAE,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;KACxB;IAOD;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAsB9C;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBrC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;CAKjC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { OrchestrationStore } from './OrchestrationStore.js';
|
|
2
|
+
/**
|
|
3
|
+
* Bridge SessionStore that splits concerns between CF and AriaFlow.
|
|
4
|
+
*
|
|
5
|
+
* CF owns messages (via AIChatAgent's cf_ai_chat_agent_messages table).
|
|
6
|
+
* AriaFlow owns orchestration state (via OrchestrationStore).
|
|
7
|
+
*
|
|
8
|
+
* On get(): reconstructs a Session by combining CF's messages with
|
|
9
|
+
* AriaFlow's orchestration state.
|
|
10
|
+
*
|
|
11
|
+
* On save(): extracts orchestration state from the Session and saves
|
|
12
|
+
* it. Does NOT save messages -- CF handles that via persistMessages().
|
|
13
|
+
*/
|
|
14
|
+
export class BridgeSessionStore {
|
|
15
|
+
orchestration;
|
|
16
|
+
cfMessages;
|
|
17
|
+
sessionId;
|
|
18
|
+
defaultAgentId;
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.orchestration = new OrchestrationStore(options.sqlExecutor);
|
|
21
|
+
this.cfMessages = options.cfMessages;
|
|
22
|
+
this.sessionId = options.sessionId;
|
|
23
|
+
this.defaultAgentId = options.defaultAgentId;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Reconstruct a Session from CF messages + orchestration state.
|
|
27
|
+
*/
|
|
28
|
+
async get(id) {
|
|
29
|
+
const orchState = await this.orchestration.get();
|
|
30
|
+
// Convert CF UIMessages to AriaFlow ModelMessages
|
|
31
|
+
const messages = convertUIMessagesToModelMessages(this.cfMessages);
|
|
32
|
+
return {
|
|
33
|
+
id: id || this.sessionId,
|
|
34
|
+
createdAt: new Date(),
|
|
35
|
+
updatedAt: new Date(),
|
|
36
|
+
messages,
|
|
37
|
+
currentAgent: orchState?.currentAgent ?? this.defaultAgentId,
|
|
38
|
+
workingMemory: orchState?.workingMemory ?? {},
|
|
39
|
+
agentStates: (orchState?.agentStates ?? {}),
|
|
40
|
+
handoffHistory: (orchState?.handoffHistory ?? []).map(h => ({
|
|
41
|
+
...h,
|
|
42
|
+
timestamp: new Date(h.timestamp),
|
|
43
|
+
})),
|
|
44
|
+
state: orchState?.state,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Save only orchestration state. CF handles message persistence.
|
|
49
|
+
*/
|
|
50
|
+
async save(session) {
|
|
51
|
+
const state = {
|
|
52
|
+
currentAgent: session.currentAgent,
|
|
53
|
+
workingMemory: session.workingMemory,
|
|
54
|
+
agentStates: session.agentStates,
|
|
55
|
+
handoffHistory: (session.handoffHistory ?? []).map(h => ({
|
|
56
|
+
from: h.from,
|
|
57
|
+
to: h.to,
|
|
58
|
+
reason: h.reason,
|
|
59
|
+
timestamp: h.timestamp instanceof Date
|
|
60
|
+
? h.timestamp.toISOString()
|
|
61
|
+
: String(h.timestamp),
|
|
62
|
+
})),
|
|
63
|
+
state: session.state,
|
|
64
|
+
};
|
|
65
|
+
await this.orchestration.save(state);
|
|
66
|
+
}
|
|
67
|
+
async delete(id) {
|
|
68
|
+
await this.orchestration.clear();
|
|
69
|
+
}
|
|
70
|
+
async list() {
|
|
71
|
+
// Single DO = single session
|
|
72
|
+
const session = await this.get(this.sessionId);
|
|
73
|
+
return session ? [session] : [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Convert CF UIMessages (parts-based) to AriaFlow ModelMessages (content-based).
|
|
78
|
+
*
|
|
79
|
+
* UIMessage has: { id, role, parts: [{type:'text', text:'...'}, {type:'tool-...'}] }
|
|
80
|
+
* ModelMessage has: { role, content: string | [{type:'text', text:'...'}] }
|
|
81
|
+
*/
|
|
82
|
+
function convertUIMessagesToModelMessages(messages) {
|
|
83
|
+
const result = [];
|
|
84
|
+
for (const msg of messages) {
|
|
85
|
+
if (msg.role === 'user') {
|
|
86
|
+
// Extract text from user message parts
|
|
87
|
+
const text = msg.parts
|
|
88
|
+
?.filter((p) => p.type === 'text')
|
|
89
|
+
.map((p) => p.text ?? '')
|
|
90
|
+
.join('') ?? '';
|
|
91
|
+
if (text) {
|
|
92
|
+
result.push({ role: 'user', content: text });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (msg.role === 'assistant') {
|
|
96
|
+
// Build content array from assistant parts
|
|
97
|
+
const content = [];
|
|
98
|
+
for (const part of msg.parts ?? []) {
|
|
99
|
+
if (part.type === 'text' && 'text' in part) {
|
|
100
|
+
content.push({ type: 'text', text: part.text });
|
|
101
|
+
}
|
|
102
|
+
else if ('toolCallId' in part && 'toolName' in part) {
|
|
103
|
+
// Tool invocation part
|
|
104
|
+
const toolPart = part;
|
|
105
|
+
content.push({
|
|
106
|
+
type: 'tool-call',
|
|
107
|
+
toolCallId: toolPart.toolCallId,
|
|
108
|
+
toolName: toolPart.toolName,
|
|
109
|
+
args: toolPart.input,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (content.length > 0) {
|
|
114
|
+
result.push({ role: 'assistant', content });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=BridgeSessionStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BridgeSessionStore.js","sourceRoot":"","sources":["../src/BridgeSessionStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SqlExecutor, OrchestrationState } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight store for AriaFlow orchestration state.
|
|
4
|
+
*
|
|
5
|
+
* This is NOT a SessionStore. CF owns message persistence via its
|
|
6
|
+
* cf_ai_chat_agent_messages table. This store only tracks the state
|
|
7
|
+
* AriaFlow needs for multi-agent orchestration:
|
|
8
|
+
*
|
|
9
|
+
* - currentAgent: which agent is active
|
|
10
|
+
* - workingMemory: key-value context injected into prompts
|
|
11
|
+
* - agentStates: per-agent state (flow node, extraction data, etc.)
|
|
12
|
+
* - handoffHistory: agent-to-agent transfer log
|
|
13
|
+
*
|
|
14
|
+
* Single table, single row per Durable Object (keyed by 'default').
|
|
15
|
+
*/
|
|
16
|
+
export declare class OrchestrationStore {
|
|
17
|
+
private sql;
|
|
18
|
+
private initialized;
|
|
19
|
+
constructor(sql: SqlExecutor);
|
|
20
|
+
private ensureTable;
|
|
21
|
+
get(): Promise<OrchestrationState | null>;
|
|
22
|
+
save(state: OrchestrationState): Promise<void>;
|
|
23
|
+
clear(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=OrchestrationStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrchestrationStore.d.ts","sourceRoot":"","sources":["../src/OrchestrationStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,WAAW,CAAS;gBAEhB,GAAG,EAAE,WAAW;IAI5B,OAAO,CAAC,WAAW;IAYb,GAAG,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAezC,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight store for AriaFlow orchestration state.
|
|
3
|
+
*
|
|
4
|
+
* This is NOT a SessionStore. CF owns message persistence via its
|
|
5
|
+
* cf_ai_chat_agent_messages table. This store only tracks the state
|
|
6
|
+
* AriaFlow needs for multi-agent orchestration:
|
|
7
|
+
*
|
|
8
|
+
* - currentAgent: which agent is active
|
|
9
|
+
* - workingMemory: key-value context injected into prompts
|
|
10
|
+
* - agentStates: per-agent state (flow node, extraction data, etc.)
|
|
11
|
+
* - handoffHistory: agent-to-agent transfer log
|
|
12
|
+
*
|
|
13
|
+
* Single table, single row per Durable Object (keyed by 'default').
|
|
14
|
+
*/
|
|
15
|
+
export class OrchestrationStore {
|
|
16
|
+
sql;
|
|
17
|
+
initialized = false;
|
|
18
|
+
constructor(sql) {
|
|
19
|
+
this.sql = sql;
|
|
20
|
+
}
|
|
21
|
+
ensureTable() {
|
|
22
|
+
if (this.initialized)
|
|
23
|
+
return;
|
|
24
|
+
this.sql `
|
|
25
|
+
CREATE TABLE IF NOT EXISTS ariaflow_orchestration (
|
|
26
|
+
id TEXT PRIMARY KEY DEFAULT 'default',
|
|
27
|
+
state TEXT NOT NULL,
|
|
28
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
29
|
+
)
|
|
30
|
+
`;
|
|
31
|
+
this.initialized = true;
|
|
32
|
+
}
|
|
33
|
+
async get() {
|
|
34
|
+
this.ensureTable();
|
|
35
|
+
const rows = this.sql `
|
|
36
|
+
SELECT state FROM ariaflow_orchestration WHERE id = 'default'
|
|
37
|
+
`.toArray();
|
|
38
|
+
if (rows.length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(rows[0].state);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async save(state) {
|
|
48
|
+
this.ensureTable();
|
|
49
|
+
const json = JSON.stringify(state);
|
|
50
|
+
this.sql `
|
|
51
|
+
INSERT INTO ariaflow_orchestration (id, state, updated_at)
|
|
52
|
+
VALUES ('default', ${json}, datetime('now'))
|
|
53
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
54
|
+
state = excluded.state,
|
|
55
|
+
updated_at = excluded.updated_at
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
async clear() {
|
|
59
|
+
this.ensureTable();
|
|
60
|
+
this.sql `DELETE FROM ariaflow_orchestration WHERE id = 'default'`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=OrchestrationStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrchestrationStore.js","sourceRoot":"","sources":["../src/OrchestrationStore.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,kBAAkB;IACrB,GAAG,CAAc;IACjB,WAAW,GAAG,KAAK,CAAC;IAE5B,YAAY,GAAgB;QAC1B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAEO,WAAW;QACjB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,GAAG,CAAA;;;;;;KAMP,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,GAAG;QACP,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAA;;KAEpB,CAAC,OAAO,EAA8B,CAAC;QAExC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEnC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAuB,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAyB;QAClC,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,CAAA;;2BAEe,IAAI;;;;KAI1B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,GAAG,CAAA,yDAAyD,CAAC;IACpE,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HarnessStreamPart } from '@ariaflowagents/core';
|
|
2
|
+
import type { StreamAdapterConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Convert AriaFlow's HarnessStreamPart generator into an SSE Response
|
|
5
|
+
* that CF's AIChatAgent._reply() can parse.
|
|
6
|
+
*
|
|
7
|
+
* CF's _streamSSEReply reads lines in the format:
|
|
8
|
+
* data: {"type":"text-start"}\n\n
|
|
9
|
+
* data: {"type":"text-delta","delta":"Hello"}\n\n
|
|
10
|
+
* data: {"type":"tool-input-available","toolCallId":"...","toolName":"...","input":{...}}\n\n
|
|
11
|
+
* data: {"type":"tool-output-available","toolCallId":"...","output":{...}}\n\n
|
|
12
|
+
* data: {"type":"data-handoff","data":{...}}\n\n
|
|
13
|
+
* data: {"type":"text-end"}\n\n
|
|
14
|
+
*
|
|
15
|
+
* CF's applyChunkToParts() then builds UIMessage parts from these chunks.
|
|
16
|
+
* CF handles persistence, broadcasting, and resumability.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createSSEResponse(stream: AsyncGenerator<HarnessStreamPart>, config?: StreamAdapterConfig): Response;
|
|
19
|
+
//# sourceMappingURL=StreamAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamAdapter.d.ts","sourceRoot":"","sources":["../src/StreamAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGtD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,CAAC,iBAAiB,CAAC,EACzC,MAAM,GAAE,mBAA2C,GAClD,QAAQ,CAuCV"}
|