@loomweaver/ag-ui 0.14.1 → 0.14.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loomweaver/ag-ui",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "LoomWeaver: open-source plugin platform for Angular workbenches. The AG-UI adapter: offers the workbench's own commands to an agent and runs what it asks for. Headless, with no transport, no UI and no agent.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"loomweaver",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"@ag-ui/core": "0.0.x",
|
|
31
|
-
"@loomweaver/plugin-sdk": "0.14.
|
|
31
|
+
"@loomweaver/plugin-sdk": "0.14.2"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type BaseEvent, type Tool, type ToolMessage } from '@ag-ui/core';
|
|
2
2
|
import type { AgentConsent, CommandArguments, PluginContext } from '@loomweaver/plugin-sdk';
|
|
3
3
|
/**
|
|
4
|
-
* The
|
|
4
|
+
* The part of a plugin context this adapter uses: what may be run, and running it. Narrower than
|
|
5
5
|
* the whole context on purpose — it says exactly what an agent reaches through here, and a plugin
|
|
6
6
|
* hands its `ctx` straight in.
|
|
7
7
|
*/
|
|
@@ -15,23 +15,23 @@ export interface PendingToolCall {
|
|
|
15
15
|
/** What it wants to pass, already readable as data but not yet checked against the command. */
|
|
16
16
|
readonly args: CommandArguments;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* How much an agent may do with the named command without asking the user, read at the moment of
|
|
19
|
+
* the call rather than from a list kept earlier.
|
|
20
20
|
*
|
|
21
21
|
* Undefined in three cases, and they are worth telling apart. The command says nothing. Or no such
|
|
22
22
|
* command is reachable, which is the workbench's refusal to make and it makes it as it always has.
|
|
23
|
-
* Or the command is one **this plugin registered
|
|
24
|
-
* caller may reach, and a
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* Or the command is one **this plugin registered without making it callable**: the list holds what
|
|
24
|
+
* a caller may reach, and such a command is not in it, while `invokeCommand` still runs it for its
|
|
25
|
+
* owner. A plugin wrote its own commands, so it is the one that knows them; whatever it decides
|
|
26
|
+
* about them belongs in this hook.
|
|
27
27
|
*
|
|
28
|
-
* Nothing here acts on it. Asking, and remembering an answer, are the
|
|
28
|
+
* Nothing here acts on it. Asking, and remembering an answer, are the plugin's, which is what this
|
|
29
29
|
* hook is for; the adapter only makes sure the statement is at hand where the decision is taken.
|
|
30
30
|
*/
|
|
31
31
|
readonly agentConsent?: AgentConsent;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
* What a
|
|
34
|
+
* What a plugin decides about a call before it runs. `run` lets it through to the workbench,
|
|
35
35
|
* `decline` answers the agent that it did not run and why, and `answer` serves the call without the
|
|
36
36
|
* workbench being involved.
|
|
37
37
|
*
|
|
@@ -47,7 +47,7 @@ export type ToolDecision = {
|
|
|
47
47
|
readonly decision: 'answer';
|
|
48
48
|
readonly content: string;
|
|
49
49
|
};
|
|
50
|
-
/** What a
|
|
50
|
+
/** What a plugin may supply when it wants a say before a call runs. */
|
|
51
51
|
export interface CommandToolOptions {
|
|
52
52
|
before?(call: PendingToolCall): ToolDecision | Promise<ToolDecision>;
|
|
53
53
|
}
|
|
@@ -60,26 +60,28 @@ export interface CommandToolOptions {
|
|
|
60
60
|
* longer there.
|
|
61
61
|
*/
|
|
62
62
|
export interface CommandTools {
|
|
63
|
-
/** The tools
|
|
63
|
+
/** The tools this plugin may reach right now, as the workbench offers them. */
|
|
64
64
|
list(): readonly Tool[];
|
|
65
65
|
/**
|
|
66
66
|
* Takes one event of the run. Answers the message to send back where the event completed a call,
|
|
67
|
-
* and nothing otherwise. Events that are not part of a tool call are ignored.
|
|
67
|
+
* and nothing otherwise. Events that are not part of a tool call are ignored. The event that ends
|
|
68
|
+
* the run answers the first call still open; ask {@link flush} for the rest.
|
|
68
69
|
*/
|
|
69
70
|
receive(event: BaseEvent): Promise<ToolMessage | null>;
|
|
70
71
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
72
|
+
* Answers one call the agent left open, or nothing once none is left, so call it until it answers
|
|
73
|
+
* nothing when the run is over. A call left open never received all of its arguments, so it is
|
|
74
|
+
* refused, saying why, and its command does not run. Only the call carried by chunks is closed by
|
|
75
|
+
* a run that finished, as the protocol defines, and runs.
|
|
74
76
|
*/
|
|
75
77
|
flush(): Promise<ToolMessage | null>;
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
78
80
|
* Connects a plugin context to an agent's tool calls.
|
|
79
81
|
*
|
|
80
|
-
* The commands the workbench offers become the tools, and a call comes back
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
82
|
+
* The commands the workbench offers become the tools, and a call comes back the same way every other
|
|
83
|
+
* trigger runs — so an agent reaches what the user could have reached, and nothing more. Nothing
|
|
84
|
+
* here opens a connection, renders anything or decides what to do; a plugin brings the stream and
|
|
85
|
+
* this carries what it says.
|
|
84
86
|
*/
|
|
85
87
|
export declare function commandTools(ctx: CommandAccess, options?: CommandToolOptions): CommandTools;
|
package/src/lib/command-tools.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventType } from '@ag-ui/core';
|
|
1
|
+
import { EventType, } from '@ag-ui/core';
|
|
2
2
|
import { readArguments } from './tool-arguments.js';
|
|
3
3
|
import { toolsFor } from './tool-definitions.js';
|
|
4
4
|
import { answerFor, refusalFor, resultFor } from './tool-results.js';
|
|
@@ -8,19 +8,22 @@ function textOf(value) {
|
|
|
8
8
|
/**
|
|
9
9
|
* Connects a plugin context to an agent's tool calls.
|
|
10
10
|
*
|
|
11
|
-
* The commands the workbench offers become the tools, and a call comes back
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* The commands the workbench offers become the tools, and a call comes back the same way every other
|
|
12
|
+
* trigger runs — so an agent reaches what the user could have reached, and nothing more. Nothing
|
|
13
|
+
* here opens a connection, renders anything or decides what to do; a plugin brings the stream and
|
|
14
|
+
* this carries what it says.
|
|
15
15
|
*/
|
|
16
16
|
export function commandTools(ctx, options = {}) {
|
|
17
17
|
const open = new Map();
|
|
18
18
|
let chunked = null;
|
|
19
|
-
const
|
|
19
|
+
const forget = (call) => {
|
|
20
20
|
open.delete(call.toolCallId);
|
|
21
21
|
if (chunked === call.toolCallId) {
|
|
22
22
|
chunked = null;
|
|
23
23
|
}
|
|
24
|
+
};
|
|
25
|
+
const finish = async (call) => {
|
|
26
|
+
forget(call);
|
|
24
27
|
const args = readArguments(call.json);
|
|
25
28
|
if (args === null) {
|
|
26
29
|
return refusalFor(call.toolCallId, 'its arguments did not arrive as readable JSON.');
|
|
@@ -40,11 +43,16 @@ export function commandTools(ctx, options = {}) {
|
|
|
40
43
|
return resultFor(call.toolCallId, await ctx.invokeCommand(call.commandId, args));
|
|
41
44
|
};
|
|
42
45
|
const flush = async () => {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
const [left] = open.values();
|
|
47
|
+
if (left === undefined) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
forget(left);
|
|
51
|
+
return refusalFor(left.toolCallId, 'the run ended before its arguments were complete.');
|
|
52
|
+
};
|
|
53
|
+
const finishRun = async () => {
|
|
54
|
+
const carried = chunked === null ? undefined : open.get(chunked);
|
|
55
|
+
return carried ? finish(carried) : flush();
|
|
48
56
|
};
|
|
49
57
|
return {
|
|
50
58
|
list: () => toolsFor(ctx.invocableCommands()),
|
|
@@ -74,7 +82,9 @@ export function commandTools(ctx, options = {}) {
|
|
|
74
82
|
case EventType.TOOL_CALL_CHUNK: {
|
|
75
83
|
return receiveChunk(raw);
|
|
76
84
|
}
|
|
77
|
-
case EventType.RUN_FINISHED:
|
|
85
|
+
case EventType.RUN_FINISHED: {
|
|
86
|
+
return finishRun();
|
|
87
|
+
}
|
|
78
88
|
case EventType.RUN_ERROR: {
|
|
79
89
|
return flush();
|
|
80
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-tools.js","sourceRoot":"","sources":["../../../../../../libs/integrations/ag-ui/src/lib/command-tools.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"command-tools.js","sourceRoot":"","sources":["../../../../../../libs/integrations/ag-ui/src/lib/command-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,14 +5,14 @@ import type { InvocableCommand } from '@loomweaver/plugin-sdk';
|
|
|
5
5
|
* name, so a call names the same identity the workbench knows it by, and nothing has to be looked up
|
|
6
6
|
* in a table on the way back.
|
|
7
7
|
*
|
|
8
|
-
* Where the command says
|
|
9
|
-
* own place for a property of a tool, under the name it was declared with, so an agent host can
|
|
8
|
+
* Where the command says how much an agent may do without asking, that statement rides in the
|
|
9
|
+
* protocol's own place for a property of a tool, under the name it was declared with, so an agent host can
|
|
10
10
|
* treat a consequential tool differently. A command that says nothing carries no `metadata` at all.
|
|
11
11
|
*
|
|
12
12
|
* A command with no description of its own gets one derived from its title. The protocol requires a
|
|
13
13
|
* description and an agent chooses between tools by reading it, so an empty string would make the
|
|
14
14
|
* tool unpickable; the title is a poor explanation but it is not nothing, and the workbench warns the
|
|
15
|
-
* author in dev mode when a command is
|
|
15
|
+
* author in dev mode when a command is callable without one.
|
|
16
16
|
*/
|
|
17
17
|
export declare function toolFor(command: InvocableCommand): Tool;
|
|
18
18
|
/** Describes every command in the list, in the order the workbench gave them. */
|
|
@@ -9,14 +9,14 @@ const SCALAR_TYPE = {
|
|
|
9
9
|
* name, so a call names the same identity the workbench knows it by, and nothing has to be looked up
|
|
10
10
|
* in a table on the way back.
|
|
11
11
|
*
|
|
12
|
-
* Where the command says
|
|
13
|
-
* own place for a property of a tool, under the name it was declared with, so an agent host can
|
|
12
|
+
* Where the command says how much an agent may do without asking, that statement rides in the
|
|
13
|
+
* protocol's own place for a property of a tool, under the name it was declared with, so an agent host can
|
|
14
14
|
* treat a consequential tool differently. A command that says nothing carries no `metadata` at all.
|
|
15
15
|
*
|
|
16
16
|
* A command with no description of its own gets one derived from its title. The protocol requires a
|
|
17
17
|
* description and an agent chooses between tools by reading it, so an empty string would make the
|
|
18
18
|
* tool unpickable; the title is a poor explanation but it is not nothing, and the workbench warns the
|
|
19
|
-
* author in dev mode when a command is
|
|
19
|
+
* author in dev mode when a command is callable without one.
|
|
20
20
|
*/
|
|
21
21
|
export function toolFor(command) {
|
|
22
22
|
return {
|