@agentforge-io/sdk-server 4.0.22 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/resources/chat.d.ts +47 -0
- package/dist/resources/chat.js +80 -0
- package/package.json +1 -1
package/dist/resources/chat.d.ts
CHANGED
|
@@ -9,6 +9,20 @@ export interface StreamMessageInput {
|
|
|
9
9
|
/** Si se omite, el server crea una conversación nueva. */
|
|
10
10
|
conversationId?: string;
|
|
11
11
|
}
|
|
12
|
+
export interface StreamMessageForAppUserInput {
|
|
13
|
+
/** Which of the App's tenant agents to run. */
|
|
14
|
+
agentId: string;
|
|
15
|
+
/** The App's own identifier for its end user — NOT signed, rides as a
|
|
16
|
+
* plain param inside the sk_live_-authenticated request (AGF-072 §4.4
|
|
17
|
+
* rationale: the authenticated channel is the proof, not a per-user
|
|
18
|
+
* signature). Threads into the conversation key
|
|
19
|
+
* `app-user:${appId}:${externalUserId}` server-side; `appId` itself is
|
|
20
|
+
* never a param, only ever resolved from the secret. */
|
|
21
|
+
externalUserId: string;
|
|
22
|
+
content: string;
|
|
23
|
+
/** Si se omite, el server crea una conversación nueva. */
|
|
24
|
+
conversationId?: string;
|
|
25
|
+
}
|
|
12
26
|
export declare class ChatResource {
|
|
13
27
|
private readonly client;
|
|
14
28
|
constructor(client: AgentForgeClient);
|
|
@@ -52,4 +66,37 @@ export declare class ChatResource {
|
|
|
52
66
|
* no pertenece al ChatToken que llama.
|
|
53
67
|
*/
|
|
54
68
|
getHistory(conversationId: string): Promise<ConversationHistory>;
|
|
69
|
+
/**
|
|
70
|
+
* AGF-073a — chat streaming AGENT-AWARE para el surface App-authenticated
|
|
71
|
+
* (`sk_live_`/`sk_test_`), server-to-server — `POST
|
|
72
|
+
* /api/v1/app-user-chat/conversations/stream` (o `.../conversations/:id/
|
|
73
|
+
* messages/stream` cuando `input.conversationId` viene seteado). Sibling
|
|
74
|
+
* ADITIVO de `streamMessage()`: NO usa ChatToken, requiere que el
|
|
75
|
+
* `AgentForgeClient` se haya construido con `appSecret`. `appId` lo
|
|
76
|
+
* resuelve el server exclusivamente del secret — nunca es un param acá
|
|
77
|
+
* tampoco (ver `APP_USER_CHAT_RUNTIME_SDD.md`).
|
|
78
|
+
*
|
|
79
|
+
* Mismo shape de eventos que `streamMessage()` — `ChatStreamEvent` con
|
|
80
|
+
* los mismos `kind`s (`conversation` | `chunk` | `stream_end` | `error`).
|
|
81
|
+
* Un consumidor no puede distinguir cuál de los dos métodos produjo el
|
|
82
|
+
* stream a partir de los eventos solos.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const af = new AgentForgeClient({ baseURL, appSecret: 'sk_live_...' });
|
|
86
|
+
* for await (const ev of af.chat.streamMessageForAppUser({
|
|
87
|
+
* agentId: 'agent-uuid',
|
|
88
|
+
* externalUserId: 'scrappydoc-user-42',
|
|
89
|
+
* content: 'hola',
|
|
90
|
+
* })) {
|
|
91
|
+
* if (ev.kind === 'conversation') conversationId = ev.conversationId;
|
|
92
|
+
* }
|
|
93
|
+
*/
|
|
94
|
+
streamMessageForAppUser(input: StreamMessageForAppUserInput): AsyncGenerator<ChatStreamEvent>;
|
|
95
|
+
/**
|
|
96
|
+
* AGF-073a companion to `streamMessageForAppUser` — historial completo de
|
|
97
|
+
* una conversación app-user, `GET /api/v1/app-user-chat/conversations/:id/
|
|
98
|
+
* messages?externalUserId=...`. `externalUserId` va como query param
|
|
99
|
+
* porque GET no lleva body; `appId` sigue resolviéndose del secret.
|
|
100
|
+
*/
|
|
101
|
+
getHistoryForAppUser(conversationId: string, externalUserId: string): Promise<ConversationHistory>;
|
|
55
102
|
}
|
package/dist/resources/chat.js
CHANGED
|
@@ -110,6 +110,86 @@ class ChatResource {
|
|
|
110
110
|
async getHistory(conversationId) {
|
|
111
111
|
return this.client.request('GET', `/api/v1/chat/conversations/${encodeURIComponent(conversationId)}/messages`);
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* AGF-073a — chat streaming AGENT-AWARE para el surface App-authenticated
|
|
115
|
+
* (`sk_live_`/`sk_test_`), server-to-server — `POST
|
|
116
|
+
* /api/v1/app-user-chat/conversations/stream` (o `.../conversations/:id/
|
|
117
|
+
* messages/stream` cuando `input.conversationId` viene seteado). Sibling
|
|
118
|
+
* ADITIVO de `streamMessage()`: NO usa ChatToken, requiere que el
|
|
119
|
+
* `AgentForgeClient` se haya construido con `appSecret`. `appId` lo
|
|
120
|
+
* resuelve el server exclusivamente del secret — nunca es un param acá
|
|
121
|
+
* tampoco (ver `APP_USER_CHAT_RUNTIME_SDD.md`).
|
|
122
|
+
*
|
|
123
|
+
* Mismo shape de eventos que `streamMessage()` — `ChatStreamEvent` con
|
|
124
|
+
* los mismos `kind`s (`conversation` | `chunk` | `stream_end` | `error`).
|
|
125
|
+
* Un consumidor no puede distinguir cuál de los dos métodos produjo el
|
|
126
|
+
* stream a partir de los eventos solos.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* const af = new AgentForgeClient({ baseURL, appSecret: 'sk_live_...' });
|
|
130
|
+
* for await (const ev of af.chat.streamMessageForAppUser({
|
|
131
|
+
* agentId: 'agent-uuid',
|
|
132
|
+
* externalUserId: 'scrappydoc-user-42',
|
|
133
|
+
* content: 'hola',
|
|
134
|
+
* })) {
|
|
135
|
+
* if (ev.kind === 'conversation') conversationId = ev.conversationId;
|
|
136
|
+
* }
|
|
137
|
+
*/
|
|
138
|
+
async *streamMessageForAppUser(input) {
|
|
139
|
+
if (!this.client.getAppSecret()) {
|
|
140
|
+
throw new Error('chat.streamMessageForAppUser requires appSecret (sk_live_/sk_test_) in ' +
|
|
141
|
+
'AgentForgeClient. This surface authenticates AS the App, not via chatToken.');
|
|
142
|
+
}
|
|
143
|
+
const path = input.conversationId
|
|
144
|
+
? `/api/v1/app-user-chat/conversations/${encodeURIComponent(input.conversationId)}/messages/stream`
|
|
145
|
+
: '/api/v1/app-user-chat/conversations/stream';
|
|
146
|
+
const res = await this.client.requestStream('POST', path, {
|
|
147
|
+
agentId: input.agentId,
|
|
148
|
+
externalUserId: input.externalUserId,
|
|
149
|
+
content: input.content,
|
|
150
|
+
});
|
|
151
|
+
if (!res.body) {
|
|
152
|
+
throw new Error('chat.streamMessageForAppUser: response has no readable body');
|
|
153
|
+
}
|
|
154
|
+
const reader = res.body.getReader();
|
|
155
|
+
const decoder = new TextDecoder();
|
|
156
|
+
let buffer = '';
|
|
157
|
+
try {
|
|
158
|
+
for (;;) {
|
|
159
|
+
const { value, done } = await reader.read();
|
|
160
|
+
if (done)
|
|
161
|
+
break;
|
|
162
|
+
buffer += decoder.decode(value, { stream: true });
|
|
163
|
+
let idx;
|
|
164
|
+
while ((idx = buffer.indexOf('\n\n')) !== -1) {
|
|
165
|
+
const frame = buffer.slice(0, idx);
|
|
166
|
+
buffer = buffer.slice(idx + 2);
|
|
167
|
+
const raw = parseRawSseFrame(frame);
|
|
168
|
+
if (!raw)
|
|
169
|
+
continue;
|
|
170
|
+
const event = toChatStreamEvent(raw);
|
|
171
|
+
if (event)
|
|
172
|
+
yield event;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
reader.releaseLock();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* AGF-073a companion to `streamMessageForAppUser` — historial completo de
|
|
182
|
+
* una conversación app-user, `GET /api/v1/app-user-chat/conversations/:id/
|
|
183
|
+
* messages?externalUserId=...`. `externalUserId` va como query param
|
|
184
|
+
* porque GET no lleva body; `appId` sigue resolviéndose del secret.
|
|
185
|
+
*/
|
|
186
|
+
async getHistoryForAppUser(conversationId, externalUserId) {
|
|
187
|
+
if (!this.client.getAppSecret()) {
|
|
188
|
+
throw new Error('chat.getHistoryForAppUser requires appSecret (sk_live_/sk_test_) in AgentForgeClient.');
|
|
189
|
+
}
|
|
190
|
+
return this.client.request('GET', `/api/v1/app-user-chat/conversations/${encodeURIComponent(conversationId)}/messages` +
|
|
191
|
+
`?externalUserId=${encodeURIComponent(externalUserId)}`);
|
|
192
|
+
}
|
|
113
193
|
}
|
|
114
194
|
exports.ChatResource = ChatResource;
|
|
115
195
|
/** Frame SSE genérico: `event: <name>\ndata: <line>\ndata: <line>...`.
|
package/package.json
CHANGED