@frockbot/plugin-bot-template 0.3.5 → 0.3.6
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": "@frockbot/plugin-bot-template",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -24,20 +24,20 @@
|
|
|
24
24
|
"typecheck": "vue-tsc --noEmit -p tsconfig.json"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@frockbot/client-core": "0.3.
|
|
28
|
-
"@frockbot/client-ui": "0.3.
|
|
29
|
-
"@frockbot/configuration-core": "0.3.
|
|
30
|
-
"@frockbot/connection-core": "0.3.
|
|
31
|
-
"@frockbot/kernel-agent-loop": "0.3.
|
|
32
|
-
"@frockbot/kernel-contracts": "0.3.
|
|
33
|
-
"@frockbot/plugin-settings": "0.3.
|
|
34
|
-
"@frockbot/plugin-shell": "0.3.
|
|
35
|
-
"@frockbot/template-core": "0.3.
|
|
27
|
+
"@frockbot/client-core": "0.3.6",
|
|
28
|
+
"@frockbot/client-ui": "0.3.6",
|
|
29
|
+
"@frockbot/configuration-core": "0.3.6",
|
|
30
|
+
"@frockbot/connection-core": "0.3.6",
|
|
31
|
+
"@frockbot/kernel-agent-loop": "0.3.6",
|
|
32
|
+
"@frockbot/kernel-contracts": "0.3.6",
|
|
33
|
+
"@frockbot/plugin-settings": "0.3.6",
|
|
34
|
+
"@frockbot/plugin-shell": "0.3.6",
|
|
35
|
+
"@frockbot/template-core": "0.3.6",
|
|
36
36
|
"cordis": "4.0.0-rc.8",
|
|
37
37
|
"vue": "3.5.41"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@frockbot/plugin-tools": "0.3.
|
|
40
|
+
"@frockbot/plugin-tools": "0.3.6",
|
|
41
41
|
"@types/bun": "1.4.0",
|
|
42
42
|
"@vitejs/plugin-vue": "6.0.8",
|
|
43
43
|
"typescript": "5.9.3",
|
package/src/agent.test.ts
CHANGED
|
@@ -81,10 +81,16 @@ function contextFor(turnType: TurnTypeV1): ToolExecutionContext {
|
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
// The tool lives in the `frockbot` namespace, so it is reached the way every
|
|
85
|
+
// namespaced tool is: through the `call_dynamic_tool` envelope (ADR 0023).
|
|
84
86
|
const call: ToolCall = {
|
|
85
87
|
id: "call-1",
|
|
86
|
-
name:
|
|
87
|
-
input: {
|
|
88
|
+
name: "call_dynamic_tool",
|
|
89
|
+
input: {
|
|
90
|
+
namespace: "frockbot",
|
|
91
|
+
toolName: BOT_EXPORT_TEMPLATE_TOOL_V1,
|
|
92
|
+
arguments: {},
|
|
93
|
+
},
|
|
88
94
|
};
|
|
89
95
|
|
|
90
96
|
async function invoke(
|
|
@@ -98,15 +104,39 @@ async function invoke(
|
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
describe("bot_export_template", () => {
|
|
101
|
-
it("is
|
|
107
|
+
it("is discoverable on chat turns only", async () => {
|
|
108
|
+
// F36: journey 10 step 1 never called this tool — the Bot invented
|
|
109
|
+
// `package_inspect_self` instead. Registered outside a namespace it
|
|
110
|
+
// appeared in no `<dynamic_tool_catalog>` entry, no
|
|
111
|
+
// `get_dynamic_tools({namespace})` result and no pattern search, so a Bot
|
|
112
|
+
// asked to share itself had nothing to find.
|
|
102
113
|
const mounted = await mount();
|
|
103
114
|
try {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
115
|
+
const discovered = async (turnType: TurnTypeV1) => {
|
|
116
|
+
const context = contextFor(turnType);
|
|
117
|
+
const discovery: ToolCall = {
|
|
118
|
+
id: "call-discover",
|
|
119
|
+
name: "get_dynamic_tools",
|
|
120
|
+
input: { pattern: "template" },
|
|
121
|
+
};
|
|
122
|
+
const preparation = await mounted.root.tools.prepare(
|
|
123
|
+
discovery,
|
|
124
|
+
context,
|
|
125
|
+
);
|
|
126
|
+
if (preparation.kind === "denied") return preparation.result.content;
|
|
127
|
+
return (await mounted.root.tools.executePrepared(preparation, context))
|
|
128
|
+
.content;
|
|
129
|
+
};
|
|
130
|
+
expect(await discovered("chat")).toContain(BOT_EXPORT_TEMPLATE_TOOL_V1);
|
|
107
131
|
for (const turnType of ["automation", "subagent"] as const) {
|
|
108
|
-
expect(
|
|
132
|
+
expect(await discovered(turnType)).not.toContain(
|
|
133
|
+
BOT_EXPORT_TEMPLATE_TOOL_V1,
|
|
134
|
+
);
|
|
109
135
|
}
|
|
136
|
+
// And it is not offered as a top-level schema, because it is namespaced.
|
|
137
|
+
expect(
|
|
138
|
+
mounted.root.tools.schemas({ turnType: "chat" }).map((t) => t.name),
|
|
139
|
+
).not.toContain(BOT_EXPORT_TEMPLATE_TOOL_V1);
|
|
110
140
|
} finally {
|
|
111
141
|
await mounted.dispose();
|
|
112
142
|
}
|
package/src/agent.ts
CHANGED
|
@@ -134,6 +134,13 @@ export function createBotExportTemplateTool(
|
|
|
134
134
|
): ToolDefinition {
|
|
135
135
|
return {
|
|
136
136
|
name: BOT_EXPORT_TEMPLATE_TOOL_V1,
|
|
137
|
+
// The `frockbot` namespace, so progressive disclosure (ADR 0023) can find
|
|
138
|
+
// it: it is listed in `<dynamic_tool_catalog>`, returned by
|
|
139
|
+
// `get_dynamic_tools({namespace:"frockbot"})`, and matched by a pattern
|
|
140
|
+
// search for "template" or "export". Registered outside a namespace it was
|
|
141
|
+
// invisible to every one of those, and a Bot asked to share itself
|
|
142
|
+
// invented `package_inspect_self` instead (journey 10 step 1, F36).
|
|
143
|
+
namespace: "frockbot",
|
|
137
144
|
description: DESCRIPTION,
|
|
138
145
|
inputSchema: {
|
|
139
146
|
type: "object",
|
|
@@ -69,11 +69,7 @@ async function plan(): Promise<void> {
|
|
|
69
69
|
/></span>
|
|
70
70
|
<span class="import__intro">
|
|
71
71
|
<strong>Import a Bot template</strong>
|
|
72
|
-
<small>
|
|
73
|
-
Paste a template link to see exactly what it would create before
|
|
74
|
-
anything happens. Importing never brings across Memory, credentials,
|
|
75
|
-
or Connections.
|
|
76
|
-
</small>
|
|
72
|
+
<small> Paste a template link to see what it would create. </small>
|
|
77
73
|
</span>
|
|
78
74
|
</header>
|
|
79
75
|
|
|
@@ -150,8 +146,8 @@ async function plan(): Promise<void> {
|
|
|
150
146
|
<h4>Missing from your catalog</h4>
|
|
151
147
|
<ul>
|
|
152
148
|
<li v-for="entry in missing" :key="entry.catalogId">
|
|
153
|
-
{{ entry.displayName }} — not in
|
|
154
|
-
|
|
149
|
+
{{ entry.displayName }} — not available in your catalog, so it will
|
|
150
|
+
be skipped.
|
|
155
151
|
</li>
|
|
156
152
|
</ul>
|
|
157
153
|
</section>
|
|
@@ -101,8 +101,8 @@ async function copyLink(share: TemplateShareRecordV1): Promise<void> {
|
|
|
101
101
|
<span class="templates__intro">
|
|
102
102
|
<strong>Share this Bot</strong>
|
|
103
103
|
<small>
|
|
104
|
-
Packs the profile,
|
|
105
|
-
|
|
104
|
+
Packs the profile, Skills, Routines, and the plugins it needs.
|
|
105
|
+
Memory, credentials, connected accounts and computer files stay
|
|
106
106
|
private.
|
|
107
107
|
</small>
|
|
108
108
|
</span>
|
|
@@ -125,11 +125,11 @@ async function copyLink(share: TemplateShareRecordV1): Promise<void> {
|
|
|
125
125
|
>
|
|
126
126
|
Packed {{ templates.summary.skills }} Skill(s),
|
|
127
127
|
{{ templates.summary.routines }} Routine(s),
|
|
128
|
-
{{ templates.summary.packages }}
|
|
128
|
+
{{ templates.summary.packages }} plugin(s) and
|
|
129
129
|
{{ templates.summary.publicServers }} public MCP server(s).
|
|
130
130
|
<template v-if="templates.summary.needsConnection > 0">
|
|
131
|
-
{{ templates.summary.needsConnection }} server(s) are left
|
|
132
|
-
|
|
131
|
+
{{ templates.summary.needsConnection }} server(s) are left for whoever
|
|
132
|
+
imports this to connect themselves.
|
|
133
133
|
</template>
|
|
134
134
|
Memory, credentials, and Connections were not included.
|
|
135
135
|
</p>
|