@reactive-agents/vue 0.9.0 → 0.10.4
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/index.d.ts +110 -0
- package/dist/index.js +116 -0
- package/package.json +2 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
|
|
3
|
+
/** Mirrors the AgentStreamEvent union from @reactive-agents/runtime. */
|
|
4
|
+
type AgentStreamEvent = {
|
|
5
|
+
readonly _tag: "TextDelta";
|
|
6
|
+
readonly text: string;
|
|
7
|
+
} | {
|
|
8
|
+
readonly _tag: "StreamCompleted";
|
|
9
|
+
readonly output: string;
|
|
10
|
+
readonly metadata: Record<string, unknown>;
|
|
11
|
+
readonly taskId?: string;
|
|
12
|
+
readonly agentId?: string;
|
|
13
|
+
} | {
|
|
14
|
+
readonly _tag: "StreamError";
|
|
15
|
+
readonly cause: string;
|
|
16
|
+
} | {
|
|
17
|
+
readonly _tag: "IterationProgress";
|
|
18
|
+
readonly iteration: number;
|
|
19
|
+
readonly maxIterations: number;
|
|
20
|
+
readonly status: string;
|
|
21
|
+
} | {
|
|
22
|
+
readonly _tag: "StreamCancelled";
|
|
23
|
+
readonly reason: string;
|
|
24
|
+
readonly iterationsCompleted: number;
|
|
25
|
+
} | {
|
|
26
|
+
readonly _tag: string;
|
|
27
|
+
readonly [key: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
type AgentHookState = "idle" | "streaming" | "completed" | "error";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Stream agent output token-by-token from an SSE endpoint.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```vue
|
|
36
|
+
* <script setup>
|
|
37
|
+
* const { text, status, error, run, cancel } = useAgentStream("/api/agent");
|
|
38
|
+
* </script>
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
declare function useAgentStream(endpoint: string, requestInit?: Omit<RequestInit, "method" | "body" | "signal">): {
|
|
42
|
+
text: Readonly<vue.Ref<string, string>>;
|
|
43
|
+
events: Readonly<vue.Ref<readonly ({
|
|
44
|
+
readonly _tag: "TextDelta";
|
|
45
|
+
readonly text: string;
|
|
46
|
+
} | {
|
|
47
|
+
readonly _tag: "StreamCompleted";
|
|
48
|
+
readonly output: string;
|
|
49
|
+
readonly metadata: {
|
|
50
|
+
readonly [x: string]: Readonly<unknown>;
|
|
51
|
+
};
|
|
52
|
+
readonly taskId?: string | undefined;
|
|
53
|
+
readonly agentId?: string | undefined;
|
|
54
|
+
} | {
|
|
55
|
+
readonly _tag: "StreamError";
|
|
56
|
+
readonly cause: string;
|
|
57
|
+
} | {
|
|
58
|
+
readonly _tag: "IterationProgress";
|
|
59
|
+
readonly iteration: number;
|
|
60
|
+
readonly maxIterations: number;
|
|
61
|
+
readonly status: string;
|
|
62
|
+
} | {
|
|
63
|
+
readonly _tag: "StreamCancelled";
|
|
64
|
+
readonly reason: string;
|
|
65
|
+
readonly iterationsCompleted: number;
|
|
66
|
+
} | {
|
|
67
|
+
readonly [x: string]: Readonly<unknown>;
|
|
68
|
+
readonly _tag: string;
|
|
69
|
+
})[], readonly ({
|
|
70
|
+
readonly _tag: "TextDelta";
|
|
71
|
+
readonly text: string;
|
|
72
|
+
} | {
|
|
73
|
+
readonly _tag: "StreamCompleted";
|
|
74
|
+
readonly output: string;
|
|
75
|
+
readonly metadata: {
|
|
76
|
+
readonly [x: string]: Readonly<unknown>;
|
|
77
|
+
};
|
|
78
|
+
readonly taskId?: string | undefined;
|
|
79
|
+
readonly agentId?: string | undefined;
|
|
80
|
+
} | {
|
|
81
|
+
readonly _tag: "StreamError";
|
|
82
|
+
readonly cause: string;
|
|
83
|
+
} | {
|
|
84
|
+
readonly _tag: "IterationProgress";
|
|
85
|
+
readonly iteration: number;
|
|
86
|
+
readonly maxIterations: number;
|
|
87
|
+
readonly status: string;
|
|
88
|
+
} | {
|
|
89
|
+
readonly _tag: "StreamCancelled";
|
|
90
|
+
readonly reason: string;
|
|
91
|
+
readonly iterationsCompleted: number;
|
|
92
|
+
} | {
|
|
93
|
+
readonly [x: string]: Readonly<unknown>;
|
|
94
|
+
readonly _tag: string;
|
|
95
|
+
})[]>>;
|
|
96
|
+
status: Readonly<vue.Ref<AgentHookState, AgentHookState>>;
|
|
97
|
+
error: Readonly<vue.Ref<string | null, string | null>>;
|
|
98
|
+
output: Readonly<vue.Ref<string | null, string | null>>;
|
|
99
|
+
run: (prompt: string, body?: Record<string, unknown>) => Promise<void>;
|
|
100
|
+
cancel: () => void;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
declare function useAgent(endpoint: string, requestInit?: Omit<RequestInit, "method" | "body">): {
|
|
104
|
+
output: Readonly<vue.Ref<string | null, string | null>>;
|
|
105
|
+
loading: Readonly<vue.Ref<boolean, boolean>>;
|
|
106
|
+
error: Readonly<vue.Ref<string | null, string | null>>;
|
|
107
|
+
run: (prompt: string, body?: Record<string, unknown>) => Promise<string>;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export { type AgentHookState, type AgentStreamEvent, useAgent, useAgentStream };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// src/use-agent-stream.ts
|
|
2
|
+
import { ref, readonly } from "vue";
|
|
3
|
+
function useAgentStream(endpoint, requestInit) {
|
|
4
|
+
const text = ref("");
|
|
5
|
+
const events = ref([]);
|
|
6
|
+
const status = ref("idle");
|
|
7
|
+
const error = ref(null);
|
|
8
|
+
const output = ref(null);
|
|
9
|
+
let abortController = null;
|
|
10
|
+
function cancel() {
|
|
11
|
+
abortController?.abort();
|
|
12
|
+
status.value = "idle";
|
|
13
|
+
}
|
|
14
|
+
async function run(prompt, body) {
|
|
15
|
+
abortController?.abort();
|
|
16
|
+
abortController = new AbortController();
|
|
17
|
+
text.value = "";
|
|
18
|
+
events.value = [];
|
|
19
|
+
error.value = null;
|
|
20
|
+
output.value = null;
|
|
21
|
+
status.value = "streaming";
|
|
22
|
+
try {
|
|
23
|
+
const res = await fetch(endpoint, {
|
|
24
|
+
...requestInit,
|
|
25
|
+
method: "POST",
|
|
26
|
+
signal: abortController.signal,
|
|
27
|
+
headers: { "Content-Type": "application/json", ...requestInit?.headers },
|
|
28
|
+
body: JSON.stringify({ prompt, ...body })
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
31
|
+
if (!res.body) throw new Error("No response body");
|
|
32
|
+
const reader = res.body.getReader();
|
|
33
|
+
const decoder = new TextDecoder();
|
|
34
|
+
let buffer = "";
|
|
35
|
+
while (true) {
|
|
36
|
+
const { done, value } = await reader.read();
|
|
37
|
+
if (done) break;
|
|
38
|
+
buffer += decoder.decode(value, { stream: true });
|
|
39
|
+
const lines = buffer.split("\n");
|
|
40
|
+
buffer = lines.pop() ?? "";
|
|
41
|
+
for (const line of lines) {
|
|
42
|
+
if (!line.startsWith("data: ")) continue;
|
|
43
|
+
const raw = line.slice(6).trim();
|
|
44
|
+
if (!raw) continue;
|
|
45
|
+
try {
|
|
46
|
+
const event = JSON.parse(raw);
|
|
47
|
+
events.value = [...events.value, event];
|
|
48
|
+
if (event._tag === "TextDelta" && "text" in event) {
|
|
49
|
+
text.value += event.text;
|
|
50
|
+
} else if (event._tag === "StreamCompleted" && "output" in event) {
|
|
51
|
+
output.value = event.output;
|
|
52
|
+
status.value = "completed";
|
|
53
|
+
return;
|
|
54
|
+
} else if (event._tag === "StreamError" && "cause" in event) {
|
|
55
|
+
throw new Error(event.cause);
|
|
56
|
+
} else if (event._tag === "StreamCancelled") {
|
|
57
|
+
status.value = "idle";
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} catch (err) {
|
|
65
|
+
if (err instanceof Error && err.name === "AbortError") return;
|
|
66
|
+
error.value = err instanceof Error ? err.message : String(err);
|
|
67
|
+
status.value = "error";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
text: readonly(text),
|
|
72
|
+
events: readonly(events),
|
|
73
|
+
status: readonly(status),
|
|
74
|
+
error: readonly(error),
|
|
75
|
+
output: readonly(output),
|
|
76
|
+
run,
|
|
77
|
+
cancel
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/use-agent.ts
|
|
82
|
+
import { ref as ref2, readonly as readonly2 } from "vue";
|
|
83
|
+
function useAgent(endpoint, requestInit) {
|
|
84
|
+
const output = ref2(null);
|
|
85
|
+
const loading = ref2(false);
|
|
86
|
+
const error = ref2(null);
|
|
87
|
+
async function run(prompt, body) {
|
|
88
|
+
loading.value = true;
|
|
89
|
+
error.value = null;
|
|
90
|
+
output.value = null;
|
|
91
|
+
try {
|
|
92
|
+
const res = await fetch(endpoint, {
|
|
93
|
+
...requestInit,
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: { "Content-Type": "application/json", ...requestInit?.headers },
|
|
96
|
+
body: JSON.stringify({ prompt, ...body })
|
|
97
|
+
});
|
|
98
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
99
|
+
const data = await res.json();
|
|
100
|
+
const result = data.output ?? data.result ?? "";
|
|
101
|
+
output.value = result;
|
|
102
|
+
return result;
|
|
103
|
+
} catch (err) {
|
|
104
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
105
|
+
error.value = msg;
|
|
106
|
+
throw err;
|
|
107
|
+
} finally {
|
|
108
|
+
loading.value = false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { output: readonly2(output), loading: readonly2(loading), error: readonly2(error), run };
|
|
112
|
+
}
|
|
113
|
+
export {
|
|
114
|
+
useAgent,
|
|
115
|
+
useAgentStream
|
|
116
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reactive-agents/vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.4",
|
|
4
4
|
"description": "Vue composables for Reactive Agents — useAgentStream, useAgent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
|
+
"bun": "./dist/index.js",
|
|
8
9
|
"types": "./dist/index.d.ts",
|
|
9
10
|
"import": "./dist/index.js",
|
|
10
11
|
"default": "./dist/index.js"
|