@dynamicagents/plugins 0.12.0 → 0.13.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 +58 -77
- package/dist/browser/index.d.ts +0 -2
- package/dist/browser/index.js +21 -27
- package/dist/claude-code/cards.d.ts +53 -0
- package/dist/claude-code/cards.js +272 -0
- package/dist/claude-code/config.d.ts +28 -63
- package/dist/claude-code/config.js +0 -11
- package/dist/claude-code/egress.d.ts +8 -1
- package/dist/claude-code/egress.js +42 -4
- package/dist/claude-code/events.d.ts +106 -9
- package/dist/claude-code/events.js +201 -56
- package/dist/claude-code/github.d.ts +39 -0
- package/dist/claude-code/github.js +82 -0
- package/dist/claude-code/index.d.ts +16 -90
- package/dist/claude-code/index.js +14 -276
- package/dist/claude-code/model.d.ts +152 -0
- package/dist/claude-code/model.js +342 -0
- package/dist/claude-code/run.d.ts +209 -112
- package/dist/claude-code/run.js +339 -138
- package/dist/claude-code/session.d.ts +131 -0
- package/dist/claude-code/session.js +285 -0
- package/dist/claude-code/spec.d.ts +46 -0
- package/dist/claude-code/spec.js +83 -0
- package/dist/claude-code/verified.d.ts +15 -0
- package/dist/claude-code/verified.js +15 -0
- package/dist/computer/context.d.ts +1 -5
- package/dist/computer/context.js +7 -10
- package/dist/computer/file-lock.js +5 -4
- package/dist/computer/gate.d.ts +4 -4
- package/dist/computer/gate.js +5 -5
- package/dist/computer/index.d.ts +40 -258
- package/dist/computer/index.js +71 -324
- package/dist/computer/paths.d.ts +36 -16
- package/dist/computer/paths.js +42 -29
- package/dist/computer/proxy.d.ts +45 -0
- package/dist/computer/proxy.js +234 -0
- package/dist/computer/render.d.ts +1 -40
- package/dist/computer/render.js +2 -68
- package/dist/computer/tools-exec.js +12 -13
- package/dist/computer/tools-file.d.ts +9 -1
- package/dist/computer/tools-file.js +22 -82
- package/dist/computer/{tools-find.d.ts → tools-grep.d.ts} +1 -1
- package/dist/computer/tools-grep.js +129 -0
- package/dist/repo/checkout.d.ts +4 -5
- package/dist/repo/checkout.js +31 -8
- package/dist/repo/context.d.ts +35 -9
- package/dist/repo/context.js +101 -49
- package/dist/repo/index.d.ts +73 -28
- package/dist/repo/index.js +112 -96
- package/dist/repo/tools-checks.d.ts +3 -0
- package/dist/repo/tools-checks.js +112 -0
- package/dist/repo/tools-clone.js +1 -1
- package/dist/repo/tools-pr.d.ts +14 -0
- package/dist/repo/{tools-forge.js → tools-pr.js} +53 -36
- package/dist/repo/tools-review.d.ts +9 -0
- package/dist/repo/tools-review.js +67 -47
- package/dist/repo/tools-worktree.js +144 -60
- package/dist/repo/tools-worktrees.d.ts +12 -0
- package/dist/repo/tools-worktrees.js +48 -0
- package/dist/repo/url.d.ts +2 -2
- package/dist/repo/url.js +7 -7
- package/dist/scratch/index.d.ts +4 -4
- package/dist/scratch/index.js +12 -11
- package/dist/{computer → workspace}/advisory.d.ts +4 -4
- package/dist/{computer → workspace}/advisory.js +2 -2
- package/dist/{computer/host → workspace}/ca-trust.d.ts +8 -1
- package/dist/{computer/host → workspace}/ca-trust.js +12 -3
- package/dist/{computer/host → workspace}/container-fault.d.ts +3 -3
- package/dist/{computer/host → workspace}/container-fault.js +23 -8
- package/dist/workspace/exec.d.ts +94 -0
- package/dist/workspace/exec.js +153 -0
- package/dist/workspace/format.d.ts +36 -0
- package/dist/workspace/format.js +57 -0
- package/dist/{computer/host → workspace}/git-host.d.ts +21 -4
- package/dist/{computer/host → workspace}/git-host.js +72 -2
- package/dist/{computer/host → workspace}/git-identity.d.ts +1 -1
- package/dist/{computer/host → workspace}/git-identity.js +1 -1
- package/dist/workspace/index.d.ts +43 -47
- package/dist/workspace/index.js +52 -112
- package/dist/{computer/host → workspace}/install-job.d.ts +4 -4
- package/dist/{computer/host → workspace}/install-job.js +276 -176
- package/dist/{computer → workspace}/install.d.ts +8 -8
- package/dist/{computer → workspace}/install.js +3 -3
- package/dist/{computer/host/workspace.d.ts → workspace/object.d.ts} +105 -27
- package/dist/{computer/host/workspace.js → workspace/object.js} +217 -48
- package/dist/workspace/open.d.ts +95 -0
- package/dist/workspace/open.js +63 -0
- package/dist/workspace/read.d.ts +16 -0
- package/dist/workspace/read.js +22 -0
- package/dist/{computer → workspace}/shell.d.ts +5 -5
- package/dist/{computer → workspace}/shell.js +6 -6
- package/dist/{computer/host → workspace}/wake.d.ts +1 -1
- package/package.json +16 -36
- package/dist/arc-agi/analysis.d.ts +0 -322
- package/dist/arc-agi/analysis.js +0 -802
- package/dist/arc-agi/client.d.ts +0 -82
- package/dist/arc-agi/client.js +0 -113
- package/dist/arc-agi/game-tools.d.ts +0 -24
- package/dist/arc-agi/game-tools.js +0 -26
- package/dist/arc-agi/index.d.ts +0 -40
- package/dist/arc-agi/index.js +0 -175
- package/dist/arc-agi/main-agent.d.ts +0 -24
- package/dist/arc-agi/main-agent.js +0 -62
- package/dist/arc-agi/recipe.d.ts +0 -48
- package/dist/arc-agi/recipe.js +0 -97
- package/dist/arc-agi/scorecard.d.ts +0 -118
- package/dist/arc-agi/scorecard.js +0 -163
- package/dist/arc-agi/soul.d.ts +0 -29
- package/dist/arc-agi/soul.js +0 -79
- package/dist/arc-agi/store.d.ts +0 -153
- package/dist/arc-agi/store.js +0 -215
- package/dist/arc-agi/tools.d.ts +0 -36
- package/dist/arc-agi/tools.js +0 -574
- package/dist/arc-agi/types.d.ts +0 -211
- package/dist/arc-agi/types.js +0 -19
- package/dist/claude-code/recipe.d.ts +0 -53
- package/dist/claude-code/recipe.js +0 -100
- package/dist/computer/read.d.ts +0 -133
- package/dist/computer/read.js +0 -200
- package/dist/computer/tools-find.js +0 -216
- package/dist/recall/index.d.ts +0 -105
- package/dist/recall/index.js +0 -181
- package/dist/repo/tools-forge.d.ts +0 -4
- package/dist/triage/index.d.ts +0 -360
- package/dist/triage/index.js +0 -311
- /package/dist/{computer/host → workspace}/container-deps.d.ts +0 -0
- /package/dist/{computer/host → workspace}/container-deps.js +0 -0
- /package/dist/{computer/host → workspace}/sync.d.ts +0 -0
- /package/dist/{computer/host → workspace}/sync.js +0 -0
- /package/dist/{computer/host → workspace}/wake.js +0 -0
package/dist/recall/index.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { embedMany, tool } from "ai";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { createWorkersAI } from "workers-ai-provider";
|
|
4
|
-
import { definePlugin } from "@dynamicagents/core";
|
|
5
|
-
import { gatewayLogFields, parseTurn, sessionText } from "@dynamicagents/core/agent";
|
|
6
|
-
/**
|
|
7
|
-
* `@dynamicagents/plugins/recall` — episodic memory over Cloudflare Vectorize.
|
|
8
|
-
*
|
|
9
|
-
* When the Session compacts, the raw messages it folds into a summary would
|
|
10
|
-
* otherwise be lost. Core announces that moment (`onMessagesDisplaced`) because
|
|
11
|
-
* core is what performs the lossy operation; this plugin is what does something
|
|
12
|
-
* about it — embedding the displaced range and upserting it, so a `recall` tool
|
|
13
|
-
* can later semantically search history that has scrolled out of the live
|
|
14
|
-
* context window.
|
|
15
|
-
*
|
|
16
|
-
* Core carries **no embedding code at all**: no `Embed` type, no
|
|
17
|
-
* `embeddingModelId`, no recall config. Putting any of it there fixes the shape
|
|
18
|
-
* of embedding for every future plugin — one model, one dimension,
|
|
19
|
-
* `string[] → number[][]` — and lets `ModelConfig` say only "the agent has an
|
|
20
|
-
* embedding model" when the true statement is "*this plugin* uses this embedding
|
|
21
|
-
* model". So the whole embedding path lives here.
|
|
22
|
-
*
|
|
23
|
-
* The namespace is always bound in code from the caller's verified identity,
|
|
24
|
-
* never model input, so one caller can never read another's archive.
|
|
25
|
-
*/
|
|
26
|
-
/** Workers-AI embedding model. 1024-dim/cosine, matching the Vectorize index. */
|
|
27
|
-
const DEFAULT_EMBEDDING_MODEL_ID = "@cf/baai/bge-m3";
|
|
28
|
-
/** Matches to return from a search. */
|
|
29
|
-
const DEFAULT_TOP_K = 5;
|
|
30
|
-
/**
|
|
31
|
-
* Stored-snippet cap. Vectorize allows roughly 10 KiB of metadata per vector,
|
|
32
|
-
* and the snippet is nearly all of it — a message longer than this is truncated
|
|
33
|
-
* rather than costing the whole upsert.
|
|
34
|
-
*/
|
|
35
|
-
const DEFAULT_METADATA_TEXT_MAX = 2000;
|
|
36
|
-
/**
|
|
37
|
-
* Build the Vectorize vectors for a batch of archived messages. Pure:
|
|
38
|
-
* `embeddings` are supplied 1:1 with `messages` (both already filtered to
|
|
39
|
-
* non-empty text). The vector `id` is the message's own id, so re-archiving on a
|
|
40
|
-
* compaction retry is an idempotent upsert; `<turn>` provenance is lifted into
|
|
41
|
-
* metadata when present.
|
|
42
|
-
*/
|
|
43
|
-
export function toRecallVectors(messages, namespace, embeddings, metadataTextMax = DEFAULT_METADATA_TEXT_MAX) {
|
|
44
|
-
return messages.map((m, i) => {
|
|
45
|
-
const text = sessionText(m);
|
|
46
|
-
const metadata = {
|
|
47
|
-
role: m.role,
|
|
48
|
-
text: text.slice(0, metadataTextMax)
|
|
49
|
-
};
|
|
50
|
-
const turn = parseTurn(text);
|
|
51
|
-
if (turn) {
|
|
52
|
-
metadata.author = turn.from;
|
|
53
|
-
metadata.authorId = turn.id;
|
|
54
|
-
metadata.channel = turn.channel;
|
|
55
|
-
metadata.at = turn.at;
|
|
56
|
-
}
|
|
57
|
-
return { id: m.id, namespace, values: embeddings[i], metadata };
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Archive a range of displaced messages into Vectorize. Embeds the non-empty
|
|
62
|
-
* texts in one batch and upserts them under `namespace`. No-op on empty input.
|
|
63
|
-
*/
|
|
64
|
-
export async function archiveMessages(index, namespace, messages, embed, metadataTextMax = DEFAULT_METADATA_TEXT_MAX) {
|
|
65
|
-
const withText = messages.filter((m) => sessionText(m).trim().length > 0);
|
|
66
|
-
if (withText.length === 0)
|
|
67
|
-
return;
|
|
68
|
-
const embeddings = await embed(withText.map((m) => sessionText(m)));
|
|
69
|
-
await index.upsert(toRecallVectors(withText, namespace, embeddings, metadataTextMax));
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Semantically search this instance's archive. Embeds the query and returns the
|
|
73
|
-
* top matches within `namespace`, mapping each vector's metadata to a compact
|
|
74
|
-
* {@link RecallResult}. Constrained to `namespace` — never a caller-supplied one.
|
|
75
|
-
*/
|
|
76
|
-
export async function recallSearch(index, namespace, query, embed, topK = DEFAULT_TOP_K) {
|
|
77
|
-
const [vector] = await embed([query]);
|
|
78
|
-
if (!vector)
|
|
79
|
-
return [];
|
|
80
|
-
const { matches } = await index.query(vector, {
|
|
81
|
-
namespace,
|
|
82
|
-
topK,
|
|
83
|
-
returnMetadata: "all"
|
|
84
|
-
});
|
|
85
|
-
return matches.map((match) => {
|
|
86
|
-
const md = (match.metadata ?? {});
|
|
87
|
-
const result = {
|
|
88
|
-
score: match.score,
|
|
89
|
-
role: md.role ?? "unknown",
|
|
90
|
-
text: md.text ?? ""
|
|
91
|
-
};
|
|
92
|
-
if (md.author)
|
|
93
|
-
result.author = md.author;
|
|
94
|
-
if (md.authorId)
|
|
95
|
-
result.authorId = md.authorId;
|
|
96
|
-
if (md.channel)
|
|
97
|
-
result.channel = md.channel;
|
|
98
|
-
if (md.at)
|
|
99
|
-
result.at = md.at;
|
|
100
|
-
return result;
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
export function recall(config) {
|
|
104
|
-
const { ai, index, namespace, aiGatewayId, agentName, embeddingModelId = DEFAULT_EMBEDDING_MODEL_ID, topK = DEFAULT_TOP_K, metadataTextMax = DEFAULT_METADATA_TEXT_MAX } = config;
|
|
105
|
-
/**
|
|
106
|
-
* Built on first use, never at module scope. Cloudflare evaluates module scope
|
|
107
|
-
* during `wrangler deploy` to validate the new version, and bindings are not
|
|
108
|
-
* populated at that point — constructing eagerly makes `createWorkersAI` throw
|
|
109
|
-
* "you must provide either a binding or credentials".
|
|
110
|
-
*
|
|
111
|
-
* The gateway goes on the embedding model and never on the provider — see
|
|
112
|
-
* core's Workers AI runtime for why setting it on both discards the model's.
|
|
113
|
-
* Only `agent` and `phase` are known here: one call embeds a whole displaced
|
|
114
|
-
* range, which can span channels, or a query the model wrote.
|
|
115
|
-
*/
|
|
116
|
-
let provider;
|
|
117
|
-
const embeddingSettings = aiGatewayId
|
|
118
|
-
? {
|
|
119
|
-
gateway: {
|
|
120
|
-
id: aiGatewayId,
|
|
121
|
-
...gatewayLogFields({ agent: agentName, phase: "embed" })
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
: {};
|
|
125
|
-
const embed = config.embed ??
|
|
126
|
-
(async (texts) => {
|
|
127
|
-
if (texts.length === 0)
|
|
128
|
-
return [];
|
|
129
|
-
provider ??= createWorkersAI({ binding: ai });
|
|
130
|
-
const { embeddings } = await embedMany({
|
|
131
|
-
model: provider.embedding(embeddingModelId, embeddingSettings),
|
|
132
|
-
values: texts
|
|
133
|
-
});
|
|
134
|
-
return embeddings;
|
|
135
|
-
});
|
|
136
|
-
return definePlugin({
|
|
137
|
-
key: "recall",
|
|
138
|
-
/**
|
|
139
|
-
* Offered only once this caller's history has actually been compacted.
|
|
140
|
-
*
|
|
141
|
-
* Before the first compaction the archive is empty by construction, and a
|
|
142
|
-
* tool whose only possible answer is "nothing here yet" costs the model a
|
|
143
|
-
* call to discover that — plus the tokens to describe it, every round.
|
|
144
|
-
*/
|
|
145
|
-
mainAgentTools: async (ctx) => {
|
|
146
|
-
if ((await ctx.session.getCompactions()).length === 0)
|
|
147
|
-
return {};
|
|
148
|
-
return {
|
|
149
|
-
recall: tool({
|
|
150
|
-
description: "Search your own older conversation history with this caller that has scrolled out of the live context window (it was summarized during compaction). Use this to recall specific past details — quotes, decisions, facts — that you no longer have verbatim. Returns the most semantically similar archived messages with their author/channel/timestamp when known.",
|
|
151
|
-
inputSchema: z.object({
|
|
152
|
-
query: z
|
|
153
|
-
.string()
|
|
154
|
-
.describe("What to look for in the archived history"),
|
|
155
|
-
limit: z
|
|
156
|
-
.number()
|
|
157
|
-
.int()
|
|
158
|
-
.min(1)
|
|
159
|
-
.max(20)
|
|
160
|
-
.optional()
|
|
161
|
-
.describe(`Max number of matches to return (default ${topK})`)
|
|
162
|
-
}),
|
|
163
|
-
// The index, the namespace and the embedder all come from the closure.
|
|
164
|
-
// The model can only ever supply a query string and a count.
|
|
165
|
-
execute: async ({ query, limit }) => ({
|
|
166
|
-
results: await recallSearch(index, namespace(), query, embed, limit ?? topK)
|
|
167
|
-
})
|
|
168
|
-
})
|
|
169
|
-
};
|
|
170
|
-
},
|
|
171
|
-
capability: "You can search your own older history with this caller — everything that has scrolled out of your live context window and been summarized. Use `recall` when you need a specific past detail verbatim (a quote, a decision, a number) rather than the gist you already have in your summary. It searches by meaning, so describe what you are looking for rather than guessing exact words.",
|
|
172
|
-
/**
|
|
173
|
-
* Compaction is about to fold these into a summary; embed and store them
|
|
174
|
-
* first. Failures are the runtime's to swallow — it fans out with
|
|
175
|
-
* `allSettled` and never lets a listener abort compaction, because history
|
|
176
|
-
* must still shorten when a side store is briefly unavailable.
|
|
177
|
-
*/
|
|
178
|
-
onMessagesDisplaced: (messages) => archiveMessages(index, namespace(), messages, embed, metadataTextMax),
|
|
179
|
-
requires: { bindings: ["VECTORIZE"] }
|
|
180
|
-
});
|
|
181
|
-
}
|
package/dist/triage/index.d.ts
DELETED
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import type { LanguageModel } from "ai";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import type { AgentPlugin } from "@dynamicagents/core";
|
|
4
|
-
import type { SessionMessage } from "@dynamicagents/core/agent";
|
|
5
|
-
/**
|
|
6
|
-
* The classifier's output. The booleans are **not** metadata for the caller —
|
|
7
|
-
* only `should_reply` is ever read. They exist to shape the generation itself:
|
|
8
|
-
* constrained decoding fills properties in schema order, so declaring them ahead
|
|
9
|
-
* of `should_reply` forces the model to commit to the sub-judgements that
|
|
10
|
-
* determine the answer — *who is this for*, and *do I have something worth
|
|
11
|
-
* adding* — before it can name a verdict. Reordering these fields, or dropping
|
|
12
|
-
* one, changes what the model reasons about; it is not cosmetic.
|
|
13
|
-
*
|
|
14
|
-
* `reason` comes last, after the verdict, on purpose: generated afterwards it
|
|
15
|
-
* justifies the decision rather than steering it, so a logged reason can never
|
|
16
|
-
* contradict the `should_reply` it explains. That is what makes it worth reading
|
|
17
|
-
* when a misclassification needs debugging.
|
|
18
|
-
*/
|
|
19
|
-
export declare const triageSchema: z.ZodObject<{
|
|
20
|
-
for_other_people: z.ZodBoolean;
|
|
21
|
-
for_another_agent: z.ZodBoolean;
|
|
22
|
-
can_contribute: z.ZodBoolean;
|
|
23
|
-
should_reply: z.ZodBoolean;
|
|
24
|
-
reason: z.ZodString;
|
|
25
|
-
}, z.core.$strip>;
|
|
26
|
-
export type TriageVerdict = z.infer<typeof triageSchema>;
|
|
27
|
-
/**
|
|
28
|
-
* The tuning half of {@link TriageConfig}: plain values, no bindings.
|
|
29
|
-
*
|
|
30
|
-
* Declare these once in a config module and spread them at the call site — see
|
|
31
|
-
* `RecallTuning` for why enumerating each field is a liability rather than just
|
|
32
|
-
* noise.
|
|
33
|
-
*/
|
|
34
|
-
export interface TriageTuning {
|
|
35
|
-
/**
|
|
36
|
-
* AI Gateway id. Pass the host's **resolved** value
|
|
37
|
-
* (`PluginHost.aiGatewayId`), so classify calls stay correlated with chat calls
|
|
38
|
-
* in one gateway.
|
|
39
|
-
*/
|
|
40
|
-
aiGatewayId?: string;
|
|
41
|
-
/**
|
|
42
|
-
* The `agent` key on the classifier's AI Gateway log rows. Pass the host's
|
|
43
|
-
* `PluginHost.agentName`, for the reason given on {@link aiGatewayId}.
|
|
44
|
-
*/
|
|
45
|
-
agentName?: string;
|
|
46
|
-
/** Workers-AI id for the classifier. Defaults to a small, fast model. */
|
|
47
|
-
modelId?: string;
|
|
48
|
-
/** Trailing messages the classifier sees. Defaults to 12. */
|
|
49
|
-
historyMessages?: number;
|
|
50
|
-
/** Per-message char cap in the prompt. Defaults to 500. */
|
|
51
|
-
messageMaxChars?: number;
|
|
52
|
-
}
|
|
53
|
-
export interface TriageConfig extends TriageTuning {
|
|
54
|
-
/** The `AI` binding. Read lazily — see {@link triage}. */
|
|
55
|
-
ai: Ai;
|
|
56
|
-
/** Test override; skips the provider entirely. */
|
|
57
|
-
model?: LanguageModel;
|
|
58
|
-
}
|
|
59
|
-
export interface TriagePromptOptions {
|
|
60
|
-
historyMessages?: number;
|
|
61
|
-
messageMaxChars?: number;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Build the classifier prompt from the tail of the conversation.
|
|
65
|
-
*
|
|
66
|
-
* A bare message is frequently unclassifiable — "yes", "thanks", "and the second
|
|
67
|
-
* one?" only resolve against what came before — and the drift being fixed is
|
|
68
|
-
* *only* visible in context, where the classifier can see the agent has been
|
|
69
|
-
* talking and that the speaker has since turned to someone else.
|
|
70
|
-
*
|
|
71
|
-
* Exported for its own tests: it is pure, so the prompt can be asserted without
|
|
72
|
-
* an LLM.
|
|
73
|
-
*/
|
|
74
|
-
export declare function buildTriagePrompt(history: SessionMessage[], options?: TriagePromptOptions): string;
|
|
75
|
-
/**
|
|
76
|
-
* Classify whether the agent should reply to the newest message in `history`.
|
|
77
|
-
*
|
|
78
|
-
* **Fails open.** Every error is caught here and answered `true`, because the
|
|
79
|
-
* two mistakes are not symmetric: a wrong reply is noise the user can see and
|
|
80
|
-
* ignore, while a wrong silence is invisible — the person who needed the agent
|
|
81
|
-
* simply never hears back and has no way to tell that anything happened. A
|
|
82
|
-
* triage outage must therefore degrade to the previous behaviour (let the loop
|
|
83
|
-
* decide), never to a silent agent.
|
|
84
|
-
*
|
|
85
|
-
* Only `should_reply` is read; the other fields exist to steer the generation
|
|
86
|
-
* (see {@link triageSchema}) and are logged, not re-derived in code.
|
|
87
|
-
*/
|
|
88
|
-
export declare function shouldReply(model: LanguageModel, history: SessionMessage[], options?: TriagePromptOptions): Promise<boolean>;
|
|
89
|
-
export declare function triage(config: TriageConfig): AgentPlugin;
|
|
90
|
-
/** The tool the model calls to end a turn without replying. */
|
|
91
|
-
export declare const NO_REPLY_TOOL_NAME = "no_reply";
|
|
92
|
-
/**
|
|
93
|
-
* Tool result when a `no_reply` call is ignored. This is only ever read by the
|
|
94
|
-
* model in one case: it has already sent something this turn (so the tool was
|
|
95
|
-
* withdrawn) yet named it anyway — the call is ignored and it must finish with a
|
|
96
|
-
* reply. When a `no_reply` call is instead honoured it ends the turn, and this
|
|
97
|
-
* result is discarded unread.
|
|
98
|
-
*/
|
|
99
|
-
export declare const NO_REPLY_IGNORED = "Ignored: you have already sent a message this turn \u2014 finish with a reply.";
|
|
100
|
-
/**
|
|
101
|
-
* End the turn without replying — the *late* counterpart to the pre-turn gate.
|
|
102
|
-
* The agent looks something up, concludes there is nothing worth adding, and
|
|
103
|
-
* declines.
|
|
104
|
-
*
|
|
105
|
-
* Deliberately an ordinary tool with an ordinary no-op `execute`: the loop, not
|
|
106
|
-
* the tool, decides what a `no_reply` call means (see {@link isNoReplyTurn}).
|
|
107
|
-
* Two things here are load-bearing:
|
|
108
|
-
*
|
|
109
|
-
* - **`execute` must exist.** Once the agent has spoken the tool is withdrawn,
|
|
110
|
-
* but the model can still name it (the SDK resolves calls against the
|
|
111
|
-
* unfiltered map); that call is ignored and the loop must continue to a real
|
|
112
|
-
* reply. `generateText` only continues while every tool call in a step
|
|
113
|
-
* produced an output, so without `execute` that step would halt with no reply
|
|
114
|
-
* text and surface as a failure. Executing normally keeps the counts equal.
|
|
115
|
-
* - **`reason` must stay optional.** A required field the model omits makes the
|
|
116
|
-
* SDK mark the call invalid and skip execution, halting the loop the same way.
|
|
117
|
-
*
|
|
118
|
-
* Wiring is the loop's: offer this tool until the agent has spoken, withdraw it
|
|
119
|
-
* after, and stop the run when {@link isNoReplyTurn} holds.
|
|
120
|
-
*/
|
|
121
|
-
export declare const noReplyTool: ({
|
|
122
|
-
title?: string;
|
|
123
|
-
providerOptions?: import("@ai-sdk/provider-utils").ProviderOptions;
|
|
124
|
-
metadata?: import("@ai-sdk/provider").JSONObject;
|
|
125
|
-
inputSchema: import("ai").FlexibleSchema<{
|
|
126
|
-
reason?: string | undefined;
|
|
127
|
-
}>;
|
|
128
|
-
contextSchema?: import("ai").FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
|
|
129
|
-
needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
|
|
130
|
-
reason?: string | undefined;
|
|
131
|
-
}, NoInfer<import("@ai-sdk/provider-utils").Context>> | undefined;
|
|
132
|
-
onInputStart?: ((options: import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
133
|
-
onInputDelta?: ((options: {
|
|
134
|
-
inputTextDelta: string;
|
|
135
|
-
} & import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
136
|
-
onInputAvailable?: ((options: {
|
|
137
|
-
input: {
|
|
138
|
-
reason?: string | undefined;
|
|
139
|
-
};
|
|
140
|
-
} & import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
141
|
-
toModelOutput?: ((options: {
|
|
142
|
-
toolCallId: string;
|
|
143
|
-
input: {
|
|
144
|
-
reason?: string | undefined;
|
|
145
|
-
};
|
|
146
|
-
output: string;
|
|
147
|
-
}) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
|
|
148
|
-
} & {
|
|
149
|
-
outputSchema?: import("ai").FlexibleSchema<string> | undefined;
|
|
150
|
-
execute: import("ai").ToolExecuteFunction<{
|
|
151
|
-
reason?: string | undefined;
|
|
152
|
-
}, string, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
153
|
-
} & {
|
|
154
|
-
description?: string | ((options: {
|
|
155
|
-
context: NoInfer<import("@ai-sdk/provider-utils").Context>;
|
|
156
|
-
experimental_sandbox?: import("ai").Experimental_SandboxSession;
|
|
157
|
-
}) => string) | undefined;
|
|
158
|
-
strict?: boolean;
|
|
159
|
-
inputExamples?: {
|
|
160
|
-
input: NoInfer<{
|
|
161
|
-
reason?: string | undefined;
|
|
162
|
-
}>;
|
|
163
|
-
}[] | undefined;
|
|
164
|
-
id?: never;
|
|
165
|
-
isProviderExecuted?: never;
|
|
166
|
-
args?: never;
|
|
167
|
-
supportsDeferredResults?: never;
|
|
168
|
-
} & {
|
|
169
|
-
type?: undefined | "function";
|
|
170
|
-
} & {
|
|
171
|
-
execute: import("ai").ToolExecuteFunction<{
|
|
172
|
-
reason?: string | undefined;
|
|
173
|
-
}, string, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
174
|
-
}) | ({
|
|
175
|
-
title?: string;
|
|
176
|
-
providerOptions?: import("@ai-sdk/provider-utils").ProviderOptions;
|
|
177
|
-
metadata?: import("@ai-sdk/provider").JSONObject;
|
|
178
|
-
inputSchema: import("ai").FlexibleSchema<{
|
|
179
|
-
reason?: string | undefined;
|
|
180
|
-
}>;
|
|
181
|
-
contextSchema?: import("ai").FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
|
|
182
|
-
needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
|
|
183
|
-
reason?: string | undefined;
|
|
184
|
-
}, NoInfer<import("@ai-sdk/provider-utils").Context>> | undefined;
|
|
185
|
-
onInputStart?: ((options: import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
186
|
-
onInputDelta?: ((options: {
|
|
187
|
-
inputTextDelta: string;
|
|
188
|
-
} & import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
189
|
-
onInputAvailable?: ((options: {
|
|
190
|
-
input: {
|
|
191
|
-
reason?: string | undefined;
|
|
192
|
-
};
|
|
193
|
-
} & import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
194
|
-
toModelOutput?: ((options: {
|
|
195
|
-
toolCallId: string;
|
|
196
|
-
input: {
|
|
197
|
-
reason?: string | undefined;
|
|
198
|
-
};
|
|
199
|
-
output: string;
|
|
200
|
-
}) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
|
|
201
|
-
} & {
|
|
202
|
-
outputSchema?: import("ai").FlexibleSchema<string> | undefined;
|
|
203
|
-
execute: import("ai").ToolExecuteFunction<{
|
|
204
|
-
reason?: string | undefined;
|
|
205
|
-
}, string, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
206
|
-
} & {
|
|
207
|
-
description?: string | ((options: {
|
|
208
|
-
context: NoInfer<import("@ai-sdk/provider-utils").Context>;
|
|
209
|
-
experimental_sandbox?: import("ai").Experimental_SandboxSession;
|
|
210
|
-
}) => string) | undefined;
|
|
211
|
-
strict?: boolean;
|
|
212
|
-
inputExamples?: {
|
|
213
|
-
input: NoInfer<{
|
|
214
|
-
reason?: string | undefined;
|
|
215
|
-
}>;
|
|
216
|
-
}[] | undefined;
|
|
217
|
-
id?: never;
|
|
218
|
-
isProviderExecuted?: never;
|
|
219
|
-
args?: never;
|
|
220
|
-
supportsDeferredResults?: never;
|
|
221
|
-
} & {
|
|
222
|
-
type: "dynamic";
|
|
223
|
-
} & {
|
|
224
|
-
execute: import("ai").ToolExecuteFunction<{
|
|
225
|
-
reason?: string | undefined;
|
|
226
|
-
}, string, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
227
|
-
}) | ({
|
|
228
|
-
title?: string;
|
|
229
|
-
providerOptions?: import("@ai-sdk/provider-utils").ProviderOptions;
|
|
230
|
-
metadata?: import("@ai-sdk/provider").JSONObject;
|
|
231
|
-
inputSchema: import("ai").FlexibleSchema<{
|
|
232
|
-
reason?: string | undefined;
|
|
233
|
-
}>;
|
|
234
|
-
contextSchema?: import("ai").FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
|
|
235
|
-
needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
|
|
236
|
-
reason?: string | undefined;
|
|
237
|
-
}, NoInfer<import("@ai-sdk/provider-utils").Context>> | undefined;
|
|
238
|
-
onInputStart?: ((options: import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
239
|
-
onInputDelta?: ((options: {
|
|
240
|
-
inputTextDelta: string;
|
|
241
|
-
} & import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
242
|
-
onInputAvailable?: ((options: {
|
|
243
|
-
input: {
|
|
244
|
-
reason?: string | undefined;
|
|
245
|
-
};
|
|
246
|
-
} & import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
247
|
-
toModelOutput?: ((options: {
|
|
248
|
-
toolCallId: string;
|
|
249
|
-
input: {
|
|
250
|
-
reason?: string | undefined;
|
|
251
|
-
};
|
|
252
|
-
output: string;
|
|
253
|
-
}) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
|
|
254
|
-
} & {
|
|
255
|
-
outputSchema?: import("ai").FlexibleSchema<string> | undefined;
|
|
256
|
-
execute: import("ai").ToolExecuteFunction<{
|
|
257
|
-
reason?: string | undefined;
|
|
258
|
-
}, string, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
259
|
-
} & {
|
|
260
|
-
type: "provider";
|
|
261
|
-
id: `${string}.${string}`;
|
|
262
|
-
args: Record<string, unknown>;
|
|
263
|
-
description?: never;
|
|
264
|
-
strict?: never;
|
|
265
|
-
inputExamples?: never;
|
|
266
|
-
} & {
|
|
267
|
-
isProviderExecuted: false;
|
|
268
|
-
supportsDeferredResults?: never;
|
|
269
|
-
} & {
|
|
270
|
-
execute: import("ai").ToolExecuteFunction<{
|
|
271
|
-
reason?: string | undefined;
|
|
272
|
-
}, string, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
273
|
-
}) | ({
|
|
274
|
-
title?: string;
|
|
275
|
-
providerOptions?: import("@ai-sdk/provider-utils").ProviderOptions;
|
|
276
|
-
metadata?: import("@ai-sdk/provider").JSONObject;
|
|
277
|
-
inputSchema: import("ai").FlexibleSchema<{
|
|
278
|
-
reason?: string | undefined;
|
|
279
|
-
}>;
|
|
280
|
-
contextSchema?: import("ai").FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
|
|
281
|
-
needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
|
|
282
|
-
reason?: string | undefined;
|
|
283
|
-
}, NoInfer<import("@ai-sdk/provider-utils").Context>> | undefined;
|
|
284
|
-
onInputStart?: ((options: import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
285
|
-
onInputDelta?: ((options: {
|
|
286
|
-
inputTextDelta: string;
|
|
287
|
-
} & import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
288
|
-
onInputAvailable?: ((options: {
|
|
289
|
-
input: {
|
|
290
|
-
reason?: string | undefined;
|
|
291
|
-
};
|
|
292
|
-
} & import("ai").ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
|
|
293
|
-
toModelOutput?: ((options: {
|
|
294
|
-
toolCallId: string;
|
|
295
|
-
input: {
|
|
296
|
-
reason?: string | undefined;
|
|
297
|
-
};
|
|
298
|
-
output: string;
|
|
299
|
-
}) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
|
|
300
|
-
} & {
|
|
301
|
-
outputSchema?: import("ai").FlexibleSchema<string> | undefined;
|
|
302
|
-
execute: import("ai").ToolExecuteFunction<{
|
|
303
|
-
reason?: string | undefined;
|
|
304
|
-
}, string, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
305
|
-
} & {
|
|
306
|
-
type: "provider";
|
|
307
|
-
id: `${string}.${string}`;
|
|
308
|
-
args: Record<string, unknown>;
|
|
309
|
-
description?: never;
|
|
310
|
-
strict?: never;
|
|
311
|
-
inputExamples?: never;
|
|
312
|
-
} & {
|
|
313
|
-
isProviderExecuted: true;
|
|
314
|
-
supportsDeferredResults?: boolean;
|
|
315
|
-
} & {
|
|
316
|
-
execute: import("ai").ToolExecuteFunction<{
|
|
317
|
-
reason?: string | undefined;
|
|
318
|
-
}, string, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
319
|
-
});
|
|
320
|
-
/**
|
|
321
|
-
* What the agent is told about {@link noReplyTool}, as a system-prompt suffix.
|
|
322
|
-
*
|
|
323
|
-
* It lives here rather than in a host's prompt file for the same reason a subtask
|
|
324
|
-
* type carries its own `capability`: everything the model is told about a
|
|
325
|
-
* capability is declared by whatever owns that capability, so uninstalling the
|
|
326
|
-
* plugin takes its advice with it. A host describing a `no_reply` tool it no
|
|
327
|
-
* longer installs is the exact drift those fields exist to end.
|
|
328
|
-
*
|
|
329
|
-
* Not a `capability` on the plugin, though, and the distinction is the design.
|
|
330
|
-
* `capability` is rendered into the soul once and is true for the whole
|
|
331
|
-
* conversation; this has to be **withdrawn mid-turn**, the moment the agent
|
|
332
|
-
* speaks, in the same `prepareStep` that withdraws the tool. Advice for a tool
|
|
333
|
-
* that is no longer on the call is worse than no advice — so the loop injects it,
|
|
334
|
-
* and the loop is what knows when.
|
|
335
|
-
*/
|
|
336
|
-
export declare const NO_REPLY_GUIDANCE: string;
|
|
337
|
-
/** The only part of a `StepResult` the no-reply predicates read. */
|
|
338
|
-
type ToolCallingStep = {
|
|
339
|
-
toolCalls: ReadonlyArray<{
|
|
340
|
-
toolName: string;
|
|
341
|
-
}>;
|
|
342
|
-
};
|
|
343
|
-
/** Whether a step calls `no_reply` at all — on its own or beside other tools. */
|
|
344
|
-
export declare function stepCallsNoReply(step: ToolCallingStep): boolean;
|
|
345
|
-
/**
|
|
346
|
-
* Whether a run declined to reply: the agent has **not sent anything this turn**
|
|
347
|
-
* (`!repliedAny`) and its final step called `no_reply`. A `no_reply` call ends
|
|
348
|
-
* the turn the moment it appears — even beside another tool, which still runs
|
|
349
|
-
* but whose result is discarded — so the first step to call it is the last. A
|
|
350
|
-
* `no_reply` after the agent already streamed content is the one thing ignored.
|
|
351
|
-
*
|
|
352
|
-
* `!repliedAny` is the runtime guard that lets `no_reply` be a *late* decision
|
|
353
|
-
* while still forbidding it once the agent has spoken. Hiding the tool from the
|
|
354
|
-
* model merely hides it; the SDK still resolves a tool call against the full,
|
|
355
|
-
* unfiltered map, so a model that names `no_reply` after speaking executes it
|
|
356
|
-
* happily — this flag is what stops that from discarding a turn the user has
|
|
357
|
-
* already seen.
|
|
358
|
-
*/
|
|
359
|
-
export declare function isNoReplyTurn(repliedAny: boolean, steps: readonly ToolCallingStep[]): boolean;
|
|
360
|
-
export {};
|