@prompty/core 2.0.0-alpha.4 → 2.0.0-alpha.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/dist/index.cjs +593 -259
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +288 -9
- package/dist/index.d.ts +288 -9
- package/dist/index.js +576 -256
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -4515,6 +4515,9 @@ var init_common = __esm({
|
|
|
4515
4515
|
});
|
|
4516
4516
|
|
|
4517
4517
|
// src/core/tool-dispatch.ts
|
|
4518
|
+
function registerTool(name, handler) {
|
|
4519
|
+
nameRegistry.set(name, handler);
|
|
4520
|
+
}
|
|
4518
4521
|
function getTool(name) {
|
|
4519
4522
|
return nameRegistry.get(name);
|
|
4520
4523
|
}
|
|
@@ -4538,12 +4541,12 @@ async function dispatchTool(toolName, args, userTools, agent, parentInputs) {
|
|
|
4538
4541
|
const result = await registeredFn(args);
|
|
4539
4542
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
4540
4543
|
}
|
|
4541
|
-
const
|
|
4542
|
-
if (!
|
|
4544
|
+
const tool2 = agent.tools?.find((t) => t.name === toolName);
|
|
4545
|
+
if (!tool2) {
|
|
4543
4546
|
const available = Object.keys(userTools).sort().join(", ") || "(none)";
|
|
4544
4547
|
return `Error: tool "${toolName}" not found in userTools or agent.tools. Available user tools: ${available}`;
|
|
4545
4548
|
}
|
|
4546
|
-
const kind =
|
|
4549
|
+
const kind = tool2.kind || "*";
|
|
4547
4550
|
let handler;
|
|
4548
4551
|
try {
|
|
4549
4552
|
handler = getToolHandler(kind);
|
|
@@ -4555,7 +4558,7 @@ async function dispatchTool(toolName, args, userTools, agent, parentInputs) {
|
|
|
4555
4558
|
}
|
|
4556
4559
|
}
|
|
4557
4560
|
return await handler.executeTool(
|
|
4558
|
-
|
|
4561
|
+
tool2,
|
|
4559
4562
|
args,
|
|
4560
4563
|
agent,
|
|
4561
4564
|
parentInputs
|
|
@@ -4581,36 +4584,36 @@ var init_tool_dispatch = __esm({
|
|
|
4581
4584
|
nameRegistry = /* @__PURE__ */ new Map();
|
|
4582
4585
|
toolHandlers = /* @__PURE__ */ new Map();
|
|
4583
4586
|
FunctionToolHandler = class {
|
|
4584
|
-
async executeTool(
|
|
4585
|
-
const name =
|
|
4587
|
+
async executeTool(tool2, _args, _agent, _parentInputs) {
|
|
4588
|
+
const name = tool2.name ?? "unknown";
|
|
4586
4589
|
throw new Error(
|
|
4587
|
-
`Function tool '${name}' declared but no callable provided. Pass it via tools: { '${name}': fn } in
|
|
4590
|
+
`Function tool '${name}' declared but no callable provided. Pass it via tools: { '${name}': fn } in invokeAgent().`
|
|
4588
4591
|
);
|
|
4589
4592
|
}
|
|
4590
4593
|
};
|
|
4591
4594
|
PromptyToolHandler = class {
|
|
4592
|
-
async executeTool(
|
|
4595
|
+
async executeTool(tool2, args, agent, _parentInputs) {
|
|
4593
4596
|
const { load: load2 } = await Promise.resolve().then(() => (init_loader(), loader_exports));
|
|
4594
|
-
const { prepare: prepare2, run: run2,
|
|
4597
|
+
const { prepare: prepare2, run: run2, invokeAgent: invokeAgent2 } = await Promise.resolve().then(() => (init_pipeline(), pipeline_exports));
|
|
4595
4598
|
const parentPath = (agent.metadata ?? {}).__source_path;
|
|
4596
4599
|
if (!parentPath) {
|
|
4597
|
-
return `Error: cannot resolve PromptyTool '${
|
|
4600
|
+
return `Error: cannot resolve PromptyTool '${tool2.name}': parent has no __source_path`;
|
|
4598
4601
|
}
|
|
4599
|
-
const childPath = (0, import_node_path2.resolve)((0, import_node_path2.dirname)(parentPath),
|
|
4602
|
+
const childPath = (0, import_node_path2.resolve)((0, import_node_path2.dirname)(parentPath), tool2.path);
|
|
4600
4603
|
const stack = (agent.metadata ?? {}).__prompty_tool_stack ?? [];
|
|
4601
4604
|
const normalizedChild = (0, import_node_path2.resolve)(childPath);
|
|
4602
4605
|
const visited = /* @__PURE__ */ new Set([...stack.map((p) => (0, import_node_path2.resolve)(p)), (0, import_node_path2.resolve)(parentPath)]);
|
|
4603
4606
|
if (visited.has(normalizedChild)) {
|
|
4604
4607
|
const chain = [...stack, parentPath, childPath].join(" \u2192 ");
|
|
4605
|
-
return `Error executing PromptyTool '${
|
|
4608
|
+
return `Error executing PromptyTool '${tool2.name}': circular reference detected: ${chain}`;
|
|
4606
4609
|
}
|
|
4607
4610
|
try {
|
|
4608
4611
|
const child = load2(childPath);
|
|
4609
4612
|
if (!child.metadata) child.metadata = {};
|
|
4610
4613
|
child.metadata.__prompty_tool_stack = [...stack, parentPath];
|
|
4611
|
-
const mode =
|
|
4614
|
+
const mode = tool2.mode ?? "single";
|
|
4612
4615
|
if (mode === "agentic") {
|
|
4613
|
-
const result = await
|
|
4616
|
+
const result = await invokeAgent2(child, args);
|
|
4614
4617
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
4615
4618
|
} else {
|
|
4616
4619
|
const messages = await prepare2(child, args);
|
|
@@ -4618,7 +4621,7 @@ var init_tool_dispatch = __esm({
|
|
|
4618
4621
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
4619
4622
|
}
|
|
4620
4623
|
} catch (err) {
|
|
4621
|
-
return `Error executing PromptyTool '${
|
|
4624
|
+
return `Error executing PromptyTool '${tool2.name}': ${err instanceof Error ? err.message : String(err)}`;
|
|
4622
4625
|
}
|
|
4623
4626
|
}
|
|
4624
4627
|
};
|
|
@@ -4645,18 +4648,216 @@ var init_tool_dispatch = __esm({
|
|
|
4645
4648
|
}
|
|
4646
4649
|
});
|
|
4647
4650
|
|
|
4651
|
+
// src/core/agent-events.ts
|
|
4652
|
+
function emitEvent(callback, eventType, data) {
|
|
4653
|
+
if (!callback) return;
|
|
4654
|
+
try {
|
|
4655
|
+
callback(eventType, data);
|
|
4656
|
+
} catch (err) {
|
|
4657
|
+
if (typeof globalThis.console?.debug === "function") {
|
|
4658
|
+
globalThis.console.debug(`Event callback error for ${eventType}:`, err);
|
|
4659
|
+
}
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
var init_agent_events = __esm({
|
|
4663
|
+
"src/core/agent-events.ts"() {
|
|
4664
|
+
"use strict";
|
|
4665
|
+
}
|
|
4666
|
+
});
|
|
4667
|
+
|
|
4668
|
+
// src/core/cancellation.ts
|
|
4669
|
+
function checkCancellation(signal) {
|
|
4670
|
+
if (signal?.aborted) {
|
|
4671
|
+
throw new CancelledError();
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4674
|
+
var CancelledError;
|
|
4675
|
+
var init_cancellation = __esm({
|
|
4676
|
+
"src/core/cancellation.ts"() {
|
|
4677
|
+
"use strict";
|
|
4678
|
+
CancelledError = class extends Error {
|
|
4679
|
+
constructor(message = "Agent loop cancelled") {
|
|
4680
|
+
super(message);
|
|
4681
|
+
this.name = "CancelledError";
|
|
4682
|
+
}
|
|
4683
|
+
};
|
|
4684
|
+
}
|
|
4685
|
+
});
|
|
4686
|
+
|
|
4687
|
+
// src/core/context.ts
|
|
4688
|
+
function estimateChars(messages) {
|
|
4689
|
+
let total = 0;
|
|
4690
|
+
for (const msg of messages) {
|
|
4691
|
+
total += msg.role.length + 4;
|
|
4692
|
+
for (const part of msg.parts) {
|
|
4693
|
+
if (part.kind === "text") {
|
|
4694
|
+
total += part.value.length;
|
|
4695
|
+
} else {
|
|
4696
|
+
total += 200;
|
|
4697
|
+
}
|
|
4698
|
+
}
|
|
4699
|
+
const toolCalls = msg.metadata?.tool_calls;
|
|
4700
|
+
if (toolCalls) {
|
|
4701
|
+
total += JSON.stringify(toolCalls).length;
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
return total;
|
|
4705
|
+
}
|
|
4706
|
+
function truncate(text2, maxLen = 200) {
|
|
4707
|
+
return text2.length <= maxLen ? text2 : text2.slice(0, maxLen) + "\u2026";
|
|
4708
|
+
}
|
|
4709
|
+
function summarizeDropped(messages) {
|
|
4710
|
+
const lines = [];
|
|
4711
|
+
for (const msg of messages) {
|
|
4712
|
+
const msgText = msg.text.trim();
|
|
4713
|
+
if (msg.role === "user" && msgText) {
|
|
4714
|
+
lines.push(`User asked: ${truncate(msgText)}`);
|
|
4715
|
+
} else if (msg.role === "assistant") {
|
|
4716
|
+
if (msgText) lines.push(`Assistant: ${truncate(msgText)}`);
|
|
4717
|
+
const toolCalls = msg.metadata?.tool_calls;
|
|
4718
|
+
if (Array.isArray(toolCalls)) {
|
|
4719
|
+
const names = toolCalls.map(
|
|
4720
|
+
(tc) => tc.name ?? (tc.function?.name ?? "?")
|
|
4721
|
+
);
|
|
4722
|
+
lines.push(` Called tools: ${names.join(", ")}`);
|
|
4723
|
+
}
|
|
4724
|
+
}
|
|
4725
|
+
}
|
|
4726
|
+
if (lines.length === 0) return "";
|
|
4727
|
+
let result = "[Context summary: ";
|
|
4728
|
+
for (const line of lines) {
|
|
4729
|
+
if (result.length + line.length > 4e3) {
|
|
4730
|
+
result += "\n... (older messages omitted)";
|
|
4731
|
+
break;
|
|
4732
|
+
}
|
|
4733
|
+
result += line + "\n";
|
|
4734
|
+
}
|
|
4735
|
+
return result.trimEnd() + "]";
|
|
4736
|
+
}
|
|
4737
|
+
function trimToContextWindow(messages, budgetChars) {
|
|
4738
|
+
if (estimateChars(messages) <= budgetChars) {
|
|
4739
|
+
return [0, []];
|
|
4740
|
+
}
|
|
4741
|
+
let systemEnd = 0;
|
|
4742
|
+
for (let i = 0; i < messages.length; i++) {
|
|
4743
|
+
if (messages[i].role !== "system") {
|
|
4744
|
+
systemEnd = i;
|
|
4745
|
+
break;
|
|
4746
|
+
}
|
|
4747
|
+
if (i === messages.length - 1) systemEnd = messages.length;
|
|
4748
|
+
}
|
|
4749
|
+
const systemMsgs = messages.slice(0, systemEnd);
|
|
4750
|
+
const rest = messages.slice(systemEnd);
|
|
4751
|
+
const summaryBudget = Math.min(5e3, Math.floor(budgetChars * 0.05));
|
|
4752
|
+
const dropped = [];
|
|
4753
|
+
while (estimateChars([...systemMsgs, ...rest]) > budgetChars - summaryBudget && rest.length > 2) {
|
|
4754
|
+
dropped.push(rest.shift());
|
|
4755
|
+
}
|
|
4756
|
+
const droppedCount = dropped.length;
|
|
4757
|
+
messages.length = 0;
|
|
4758
|
+
messages.push(...systemMsgs);
|
|
4759
|
+
if (droppedCount > 0) {
|
|
4760
|
+
const summaryText = summarizeDropped(dropped);
|
|
4761
|
+
if (summaryText) {
|
|
4762
|
+
messages.push(new Message("user", [{ kind: "text", value: summaryText }]));
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
messages.push(...rest);
|
|
4766
|
+
return [droppedCount, dropped];
|
|
4767
|
+
}
|
|
4768
|
+
var init_context2 = __esm({
|
|
4769
|
+
"src/core/context.ts"() {
|
|
4770
|
+
"use strict";
|
|
4771
|
+
init_types();
|
|
4772
|
+
}
|
|
4773
|
+
});
|
|
4774
|
+
|
|
4775
|
+
// src/core/guardrails.ts
|
|
4776
|
+
var GuardrailError, Guardrails;
|
|
4777
|
+
var init_guardrails = __esm({
|
|
4778
|
+
"src/core/guardrails.ts"() {
|
|
4779
|
+
"use strict";
|
|
4780
|
+
GuardrailError = class extends Error {
|
|
4781
|
+
reason;
|
|
4782
|
+
constructor(reason) {
|
|
4783
|
+
super(`Guardrail denied: ${reason}`);
|
|
4784
|
+
this.name = "GuardrailError";
|
|
4785
|
+
this.reason = reason;
|
|
4786
|
+
}
|
|
4787
|
+
};
|
|
4788
|
+
Guardrails = class {
|
|
4789
|
+
inputHook;
|
|
4790
|
+
outputHook;
|
|
4791
|
+
toolHook;
|
|
4792
|
+
constructor(options) {
|
|
4793
|
+
this.inputHook = options?.input;
|
|
4794
|
+
this.outputHook = options?.output;
|
|
4795
|
+
this.toolHook = options?.tool;
|
|
4796
|
+
}
|
|
4797
|
+
checkInput(messages) {
|
|
4798
|
+
if (!this.inputHook) return { allowed: true };
|
|
4799
|
+
return this.inputHook(messages);
|
|
4800
|
+
}
|
|
4801
|
+
checkOutput(message) {
|
|
4802
|
+
if (!this.outputHook) return { allowed: true };
|
|
4803
|
+
return this.outputHook(message);
|
|
4804
|
+
}
|
|
4805
|
+
checkTool(name, args) {
|
|
4806
|
+
if (!this.toolHook) return { allowed: true };
|
|
4807
|
+
return this.toolHook(name, args);
|
|
4808
|
+
}
|
|
4809
|
+
};
|
|
4810
|
+
}
|
|
4811
|
+
});
|
|
4812
|
+
|
|
4813
|
+
// src/core/structured.ts
|
|
4814
|
+
function createStructuredResult(data, rawJson) {
|
|
4815
|
+
const result = { ...data };
|
|
4816
|
+
Object.defineProperty(result, StructuredResultSymbol, {
|
|
4817
|
+
value: rawJson,
|
|
4818
|
+
writable: false,
|
|
4819
|
+
enumerable: false,
|
|
4820
|
+
configurable: false
|
|
4821
|
+
});
|
|
4822
|
+
return result;
|
|
4823
|
+
}
|
|
4824
|
+
function isStructuredResult(value) {
|
|
4825
|
+
return typeof value === "object" && value !== null && StructuredResultSymbol in value;
|
|
4826
|
+
}
|
|
4827
|
+
function cast(result, validator) {
|
|
4828
|
+
let jsonStr;
|
|
4829
|
+
if (isStructuredResult(result)) {
|
|
4830
|
+
jsonStr = result[StructuredResultSymbol];
|
|
4831
|
+
} else if (typeof result === "string") {
|
|
4832
|
+
jsonStr = result;
|
|
4833
|
+
} else {
|
|
4834
|
+
jsonStr = JSON.stringify(result);
|
|
4835
|
+
}
|
|
4836
|
+
const parsed = JSON.parse(jsonStr);
|
|
4837
|
+
if (validator) {
|
|
4838
|
+
return validator(parsed);
|
|
4839
|
+
}
|
|
4840
|
+
return parsed;
|
|
4841
|
+
}
|
|
4842
|
+
var StructuredResultSymbol;
|
|
4843
|
+
var init_structured = __esm({
|
|
4844
|
+
"src/core/structured.ts"() {
|
|
4845
|
+
"use strict";
|
|
4846
|
+
StructuredResultSymbol = /* @__PURE__ */ Symbol("prompty.rawJson");
|
|
4847
|
+
}
|
|
4848
|
+
});
|
|
4849
|
+
|
|
4648
4850
|
// src/core/pipeline.ts
|
|
4649
4851
|
var pipeline_exports = {};
|
|
4650
4852
|
__export(pipeline_exports, {
|
|
4651
|
-
|
|
4652
|
-
|
|
4853
|
+
invoke: () => invoke,
|
|
4854
|
+
invokeAgent: () => invokeAgent,
|
|
4653
4855
|
parse: () => parse,
|
|
4654
4856
|
prepare: () => prepare,
|
|
4655
4857
|
process: () => process2,
|
|
4656
4858
|
render: () => render,
|
|
4657
4859
|
resolveBindings: () => resolveBindings,
|
|
4658
4860
|
run: () => run,
|
|
4659
|
-
runAgent: () => runAgent,
|
|
4660
4861
|
validateInputs: () => validateInputs
|
|
4661
4862
|
});
|
|
4662
4863
|
function sanitizeNonces(value) {
|
|
@@ -4833,8 +5034,8 @@ async function run(agent, messages, options) {
|
|
|
4833
5034
|
return result;
|
|
4834
5035
|
});
|
|
4835
5036
|
}
|
|
4836
|
-
async function
|
|
4837
|
-
return traceSpan("
|
|
5037
|
+
async function invoke(prompt, inputs, options) {
|
|
5038
|
+
return traceSpan("invoke", async (emit) => {
|
|
4838
5039
|
const agent = typeof prompt === "string" ? await traceSpan("load", async (loadEmit) => {
|
|
4839
5040
|
loadEmit("signature", "prompty.load");
|
|
4840
5041
|
loadEmit("description", "Load a prompty file.");
|
|
@@ -4843,12 +5044,15 @@ async function execute(prompt, inputs, options) {
|
|
|
4843
5044
|
loadEmit("result", serializeAgent(loaded));
|
|
4844
5045
|
return loaded;
|
|
4845
5046
|
}) : prompt;
|
|
4846
|
-
emit("signature", "prompty.
|
|
4847
|
-
emit("description", "
|
|
5047
|
+
emit("signature", "prompty.invoke");
|
|
5048
|
+
emit("description", "Invoke a prompty");
|
|
4848
5049
|
emit("inputs", { prompt: serializeAgent(agent), inputs: inputs ?? {} });
|
|
4849
5050
|
const messages = await prepare(agent, inputs);
|
|
4850
5051
|
const result = await run(agent, messages, options);
|
|
4851
5052
|
emit("result", result);
|
|
5053
|
+
if (options?.validator) {
|
|
5054
|
+
return cast(result, options.validator);
|
|
5055
|
+
}
|
|
4852
5056
|
return result;
|
|
4853
5057
|
});
|
|
4854
5058
|
}
|
|
@@ -4870,7 +5074,7 @@ function isAsyncIterable(value) {
|
|
|
4870
5074
|
function isToolCallLike(item) {
|
|
4871
5075
|
return typeof item === "object" && item !== null && "id" in item && "name" in item && "arguments" in item;
|
|
4872
5076
|
}
|
|
4873
|
-
async function consumeStream(agent, response) {
|
|
5077
|
+
async function consumeStream(agent, response, onEvent) {
|
|
4874
5078
|
const processed = await process2(agent, response);
|
|
4875
5079
|
const toolCalls = [];
|
|
4876
5080
|
const textParts = [];
|
|
@@ -4880,96 +5084,17 @@ async function consumeStream(agent, response) {
|
|
|
4880
5084
|
toolCalls.push(item);
|
|
4881
5085
|
} else if (typeof item === "string") {
|
|
4882
5086
|
textParts.push(item);
|
|
5087
|
+
emitEvent(onEvent, "token", { token: item });
|
|
4883
5088
|
}
|
|
4884
5089
|
}
|
|
4885
5090
|
} else if (typeof processed === "string") {
|
|
4886
5091
|
textParts.push(processed);
|
|
5092
|
+
emitEvent(onEvent, "token", { token: processed });
|
|
4887
5093
|
}
|
|
4888
5094
|
return { toolCalls, content: textParts.join("") };
|
|
4889
5095
|
}
|
|
4890
|
-
async function
|
|
4891
|
-
const
|
|
4892
|
-
const apiType = agent.model?.apiType || "chat";
|
|
4893
|
-
const messages = [];
|
|
4894
|
-
const toolInputs = [];
|
|
4895
|
-
if (provider === "anthropic") {
|
|
4896
|
-
const rawContent = [];
|
|
4897
|
-
if (textContent) rawContent.push({ type: "text", text: textContent });
|
|
4898
|
-
for (const tc of toolCalls) {
|
|
4899
|
-
rawContent.push({
|
|
4900
|
-
type: "tool_use",
|
|
4901
|
-
id: tc.id,
|
|
4902
|
-
name: tc.name,
|
|
4903
|
-
input: JSON.parse(tc.arguments)
|
|
4904
|
-
});
|
|
4905
|
-
}
|
|
4906
|
-
messages.push(
|
|
4907
|
-
new Message("assistant", textContent ? [text(textContent)] : [], { content: rawContent })
|
|
4908
|
-
);
|
|
4909
|
-
} else if (apiType === "responses") {
|
|
4910
|
-
for (const tc of toolCalls) {
|
|
4911
|
-
messages.push(
|
|
4912
|
-
new Message("assistant", [], {
|
|
4913
|
-
responses_function_call: {
|
|
4914
|
-
type: "function_call",
|
|
4915
|
-
call_id: tc.id,
|
|
4916
|
-
name: tc.name,
|
|
4917
|
-
arguments: tc.arguments
|
|
4918
|
-
}
|
|
4919
|
-
})
|
|
4920
|
-
);
|
|
4921
|
-
}
|
|
4922
|
-
} else {
|
|
4923
|
-
const rawToolCalls = toolCalls.map((tc) => ({
|
|
4924
|
-
id: tc.id,
|
|
4925
|
-
type: "function",
|
|
4926
|
-
function: { name: tc.name, arguments: tc.arguments }
|
|
4927
|
-
}));
|
|
4928
|
-
messages.push(
|
|
4929
|
-
new Message("assistant", textContent ? [text(textContent)] : [], {
|
|
4930
|
-
tool_calls: rawToolCalls
|
|
4931
|
-
})
|
|
4932
|
-
);
|
|
4933
|
-
}
|
|
4934
|
-
const toolResultBlocks = [];
|
|
4935
|
-
for (const tc of toolCalls) {
|
|
4936
|
-
let result;
|
|
4937
|
-
let parsedArgs;
|
|
4938
|
-
try {
|
|
4939
|
-
parsedArgs = JSON.parse(tc.arguments);
|
|
4940
|
-
if (parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
4941
|
-
parsedArgs = resolveBindings(agent, tc.name, parsedArgs, parentInputs);
|
|
4942
|
-
}
|
|
4943
|
-
result = await traceSpan(tc.name, async (toolEmit) => {
|
|
4944
|
-
toolEmit("signature", `prompty.tool.${tc.name}`);
|
|
4945
|
-
toolEmit("description", `Execute tool: ${tc.name}`);
|
|
4946
|
-
toolEmit("inputs", { arguments: parsedArgs, id: tc.id });
|
|
4947
|
-
const r = await dispatchTool(tc.name, parsedArgs, tools, agent, parentInputs ?? {});
|
|
4948
|
-
toolEmit("result", r);
|
|
4949
|
-
return r;
|
|
4950
|
-
});
|
|
4951
|
-
} catch (err) {
|
|
4952
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
4953
|
-
}
|
|
4954
|
-
toolInputs.push({ name: tc.name, arguments: parsedArgs, id: tc.id, result });
|
|
4955
|
-
if (provider === "anthropic") {
|
|
4956
|
-
toolResultBlocks.push({ type: "tool_result", tool_use_id: tc.id, content: result });
|
|
4957
|
-
} else {
|
|
4958
|
-
messages.push(
|
|
4959
|
-
new Message("tool", [text(result)], { tool_call_id: tc.id, name: tc.name })
|
|
4960
|
-
);
|
|
4961
|
-
}
|
|
4962
|
-
}
|
|
4963
|
-
if (provider === "anthropic" && toolResultBlocks.length > 0) {
|
|
4964
|
-
messages.push(new Message("user", [], { tool_results: toolResultBlocks }));
|
|
4965
|
-
}
|
|
4966
|
-
if (parentEmit) {
|
|
4967
|
-
parentEmit("inputs", { tool_calls: toolInputs });
|
|
4968
|
-
}
|
|
4969
|
-
return messages;
|
|
4970
|
-
}
|
|
4971
|
-
async function executeAgent(prompt, inputs, options) {
|
|
4972
|
-
return traceSpan("executeAgent", async (emit) => {
|
|
5096
|
+
async function invokeAgent(prompt, inputs, options) {
|
|
5097
|
+
const rawResult = await traceSpan("invokeAgent", async (emit) => {
|
|
4973
5098
|
const agent = typeof prompt === "string" ? await traceSpan("load", async (loadEmit) => {
|
|
4974
5099
|
loadEmit("signature", "prompty.load");
|
|
4975
5100
|
loadEmit("description", "Load a prompty file.");
|
|
@@ -4980,21 +5105,72 @@ async function executeAgent(prompt, inputs, options) {
|
|
|
4980
5105
|
}) : prompt;
|
|
4981
5106
|
const tools = options?.tools ?? {};
|
|
4982
5107
|
const maxIterations = options?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
4983
|
-
|
|
4984
|
-
|
|
5108
|
+
const onEvent = options?.onEvent;
|
|
5109
|
+
const signal = options?.signal;
|
|
5110
|
+
const contextBudget = options?.contextBudget;
|
|
5111
|
+
const guardrails = options?.guardrails;
|
|
5112
|
+
const steering = options?.steering;
|
|
5113
|
+
const parallelToolCalls = options?.parallelToolCalls ?? false;
|
|
5114
|
+
emit("signature", "prompty.invokeAgent");
|
|
5115
|
+
emit("description", "Invoke a prompty with tool calling");
|
|
4985
5116
|
emit("inputs", { prompt: serializeAgent(agent), tools: Object.keys(tools), inputs: inputs ?? {} });
|
|
4986
|
-
|
|
5117
|
+
let messages = await prepare(agent, inputs);
|
|
4987
5118
|
const parentInputs = inputs ?? {};
|
|
4988
5119
|
const provider = resolveProvider(agent);
|
|
4989
5120
|
const executor = getExecutor(provider);
|
|
4990
|
-
let response =
|
|
5121
|
+
let response = null;
|
|
4991
5122
|
let iteration = 0;
|
|
4992
5123
|
while (true) {
|
|
5124
|
+
try {
|
|
5125
|
+
checkCancellation(signal);
|
|
5126
|
+
} catch (err) {
|
|
5127
|
+
emitEvent(onEvent, "cancelled", {});
|
|
5128
|
+
throw err;
|
|
5129
|
+
}
|
|
5130
|
+
if (steering) {
|
|
5131
|
+
const pending = steering.drain();
|
|
5132
|
+
if (pending.length > 0) {
|
|
5133
|
+
messages.push(...pending);
|
|
5134
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5135
|
+
emitEvent(onEvent, "status", { message: `Injected ${pending.length} steering message(s)` });
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
if (contextBudget !== void 0) {
|
|
5139
|
+
const [droppedCount] = trimToContextWindow(messages, contextBudget);
|
|
5140
|
+
if (droppedCount > 0) {
|
|
5141
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5142
|
+
emitEvent(onEvent, "status", { message: `Trimmed ${droppedCount} messages for context budget` });
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
if (guardrails) {
|
|
5146
|
+
const result2 = guardrails.checkInput(messages);
|
|
5147
|
+
if (!result2.allowed) {
|
|
5148
|
+
emitEvent(onEvent, "error", { message: `Input guardrail denied: ${result2.reason}` });
|
|
5149
|
+
throw new GuardrailError(result2.reason ?? "Input guardrail denied");
|
|
5150
|
+
}
|
|
5151
|
+
if (result2.rewrite) messages = result2.rewrite;
|
|
5152
|
+
}
|
|
5153
|
+
try {
|
|
5154
|
+
checkCancellation(signal);
|
|
5155
|
+
} catch (err) {
|
|
5156
|
+
emitEvent(onEvent, "cancelled", {});
|
|
5157
|
+
throw err;
|
|
5158
|
+
}
|
|
5159
|
+
response = await executor.execute(agent, messages);
|
|
4993
5160
|
if (isAsyncIterable(response)) {
|
|
4994
|
-
const { toolCalls, content } = await consumeStream(agent, response);
|
|
5161
|
+
const { toolCalls, content } = await consumeStream(agent, response, onEvent);
|
|
5162
|
+
if (guardrails && content) {
|
|
5163
|
+
const assistantMsg = new Message("assistant", [text(content)]);
|
|
5164
|
+
const gr = guardrails.checkOutput(assistantMsg);
|
|
5165
|
+
if (!gr.allowed) {
|
|
5166
|
+
emitEvent(onEvent, "error", { message: `Output guardrail denied: ${gr.reason}` });
|
|
5167
|
+
throw new GuardrailError(gr.reason ?? "Output guardrail denied");
|
|
5168
|
+
}
|
|
5169
|
+
}
|
|
4995
5170
|
if (toolCalls.length === 0) {
|
|
4996
5171
|
emit("iterations", iteration);
|
|
4997
5172
|
emit("result", content);
|
|
5173
|
+
emitEvent(onEvent, "done", { response: content, messages });
|
|
4998
5174
|
return content;
|
|
4999
5175
|
}
|
|
5000
5176
|
iteration++;
|
|
@@ -5004,17 +5180,57 @@ async function executeAgent(prompt, inputs, options) {
|
|
|
5004
5180
|
);
|
|
5005
5181
|
}
|
|
5006
5182
|
const toolMessages2 = await traceSpan("toolCalls", async (toolEmit) => {
|
|
5007
|
-
toolEmit("signature", "prompty.
|
|
5183
|
+
toolEmit("signature", "prompty.invokeAgent.toolCalls");
|
|
5008
5184
|
toolEmit("description", `Tool call round ${iteration}`);
|
|
5009
|
-
const result2 = await
|
|
5185
|
+
const result2 = await buildToolMessagesFromCallsWithExtensions(
|
|
5186
|
+
toolCalls,
|
|
5187
|
+
content,
|
|
5188
|
+
tools,
|
|
5189
|
+
agent,
|
|
5190
|
+
parentInputs,
|
|
5191
|
+
toolEmit,
|
|
5192
|
+
{ onEvent, signal, guardrails, parallel: parallelToolCalls }
|
|
5193
|
+
);
|
|
5010
5194
|
toolEmit("result", result2.map((m) => ({ role: m.role, content: m.parts.map((p) => p.value ?? "").join(""), metadata: m.metadata })));
|
|
5011
5195
|
return result2;
|
|
5012
5196
|
});
|
|
5013
5197
|
messages.push(...toolMessages2);
|
|
5014
|
-
|
|
5198
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5015
5199
|
continue;
|
|
5016
5200
|
}
|
|
5017
|
-
if (!hasToolCalls(response))
|
|
5201
|
+
if (!hasToolCalls(response)) {
|
|
5202
|
+
const finalResult = options?.raw ? response : await process2(agent, response);
|
|
5203
|
+
if (guardrails) {
|
|
5204
|
+
const contentStr = typeof finalResult === "string" ? finalResult : JSON.stringify(finalResult);
|
|
5205
|
+
const assistantMsg = new Message("assistant", [text(contentStr)]);
|
|
5206
|
+
const gr = guardrails.checkOutput(assistantMsg);
|
|
5207
|
+
if (!gr.allowed) {
|
|
5208
|
+
emitEvent(onEvent, "error", { message: `Output guardrail denied: ${gr.reason}` });
|
|
5209
|
+
throw new GuardrailError(gr.reason ?? "Output guardrail denied");
|
|
5210
|
+
}
|
|
5211
|
+
if (gr.rewrite !== void 0) {
|
|
5212
|
+
emit("iterations", iteration);
|
|
5213
|
+
emit("result", gr.rewrite);
|
|
5214
|
+
emitEvent(onEvent, "done", { response: gr.rewrite, messages });
|
|
5215
|
+
return gr.rewrite;
|
|
5216
|
+
}
|
|
5217
|
+
}
|
|
5218
|
+
emit("iterations", iteration);
|
|
5219
|
+
emit("result", finalResult);
|
|
5220
|
+
emitEvent(onEvent, "done", { response: finalResult, messages });
|
|
5221
|
+
return finalResult;
|
|
5222
|
+
}
|
|
5223
|
+
if (guardrails) {
|
|
5224
|
+
const { textContent } = extractToolInfo(response);
|
|
5225
|
+
if (textContent) {
|
|
5226
|
+
const assistantMsg = new Message("assistant", [text(textContent)]);
|
|
5227
|
+
const gr = guardrails.checkOutput(assistantMsg);
|
|
5228
|
+
if (!gr.allowed) {
|
|
5229
|
+
emitEvent(onEvent, "error", { message: `Output guardrail denied: ${gr.reason}` });
|
|
5230
|
+
throw new GuardrailError(gr.reason ?? "Output guardrail denied");
|
|
5231
|
+
}
|
|
5232
|
+
}
|
|
5233
|
+
}
|
|
5018
5234
|
iteration++;
|
|
5019
5235
|
if (iteration > maxIterations) {
|
|
5020
5236
|
throw new Error(
|
|
@@ -5022,24 +5238,37 @@ async function executeAgent(prompt, inputs, options) {
|
|
|
5022
5238
|
);
|
|
5023
5239
|
}
|
|
5024
5240
|
const toolMessages = await traceSpan("toolCalls", async (toolEmit) => {
|
|
5025
|
-
toolEmit("signature", "prompty.
|
|
5241
|
+
toolEmit("signature", "prompty.invokeAgent.toolCalls");
|
|
5026
5242
|
toolEmit("description", `Tool call round ${iteration}`);
|
|
5027
|
-
const result2 = await
|
|
5243
|
+
const result2 = await buildToolResultMessagesWithExtensions(
|
|
5244
|
+
response,
|
|
5245
|
+
tools,
|
|
5246
|
+
agent,
|
|
5247
|
+
parentInputs,
|
|
5248
|
+
toolEmit,
|
|
5249
|
+
{ onEvent, signal, guardrails, parallel: parallelToolCalls }
|
|
5250
|
+
);
|
|
5028
5251
|
toolEmit("result", result2.map((m) => ({ role: m.role, content: m.parts.map((p) => p.value ?? "").join(""), metadata: m.metadata })));
|
|
5029
5252
|
return result2;
|
|
5030
5253
|
});
|
|
5031
5254
|
messages.push(...toolMessages);
|
|
5032
|
-
|
|
5255
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5033
5256
|
}
|
|
5034
5257
|
emit("iterations", iteration);
|
|
5035
5258
|
if (options?.raw) {
|
|
5036
5259
|
emit("result", response);
|
|
5260
|
+
emitEvent(onEvent, "done", { response, messages });
|
|
5037
5261
|
return response;
|
|
5038
5262
|
}
|
|
5039
5263
|
const result = await process2(agent, response);
|
|
5040
5264
|
emit("result", result);
|
|
5265
|
+
emitEvent(onEvent, "done", { response: result, messages });
|
|
5041
5266
|
return result;
|
|
5042
5267
|
});
|
|
5268
|
+
if (options?.validator) {
|
|
5269
|
+
return cast(rawResult, options.validator);
|
|
5270
|
+
}
|
|
5271
|
+
return rawResult;
|
|
5043
5272
|
}
|
|
5044
5273
|
function expandThreads(messages, nonces, inputs) {
|
|
5045
5274
|
if (nonces.size === 0) return messages;
|
|
@@ -5108,160 +5337,138 @@ function hasToolCalls(response) {
|
|
|
5108
5337
|
}
|
|
5109
5338
|
return false;
|
|
5110
5339
|
}
|
|
5111
|
-
|
|
5340
|
+
function extractToolInfo(response) {
|
|
5341
|
+
if (typeof response !== "object" || response === null) {
|
|
5342
|
+
return { toolCalls: [], textContent: "" };
|
|
5343
|
+
}
|
|
5112
5344
|
const r = response;
|
|
5113
5345
|
if (Array.isArray(r.content) && r.stop_reason === "tool_use") {
|
|
5114
|
-
|
|
5346
|
+
const content = r.content;
|
|
5347
|
+
const toolCalls = content.filter((b) => b.type === "tool_use").map((b) => ({
|
|
5348
|
+
id: b.id,
|
|
5349
|
+
name: b.name,
|
|
5350
|
+
arguments: JSON.stringify(b.input)
|
|
5351
|
+
}));
|
|
5352
|
+
const textContent = content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
5353
|
+
return { toolCalls, textContent };
|
|
5115
5354
|
}
|
|
5116
5355
|
if (r.object === "response" && Array.isArray(r.output)) {
|
|
5117
|
-
|
|
5356
|
+
const funcCalls = r.output.filter(
|
|
5357
|
+
(item) => item.type === "function_call"
|
|
5358
|
+
);
|
|
5359
|
+
const toolCalls = funcCalls.map((fc) => ({
|
|
5360
|
+
id: fc.call_id ?? fc.id ?? "",
|
|
5361
|
+
call_id: fc.call_id ?? fc.id ?? "",
|
|
5362
|
+
name: fc.name,
|
|
5363
|
+
arguments: fc.arguments ?? "{}"
|
|
5364
|
+
}));
|
|
5365
|
+
return { toolCalls, textContent: "" };
|
|
5118
5366
|
}
|
|
5119
|
-
return buildOpenAIToolResultMessages(r, tools, agent, parentInputs, parentEmit);
|
|
5120
|
-
}
|
|
5121
|
-
async function buildOpenAIToolResultMessages(r, tools, agent, parentInputs, parentEmit) {
|
|
5122
5367
|
const choices = r.choices;
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
for (const tc of toolCalls) {
|
|
5135
|
-
const fn = tc.function;
|
|
5136
|
-
const toolName = fn.name;
|
|
5137
|
-
const toolCallId = tc.id;
|
|
5138
|
-
let result;
|
|
5139
|
-
let parsedArgs;
|
|
5140
|
-
try {
|
|
5141
|
-
parsedArgs = JSON.parse(fn.arguments);
|
|
5142
|
-
if (agent && parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
5143
|
-
parsedArgs = resolveBindings(agent, toolName, parsedArgs, parentInputs);
|
|
5144
|
-
}
|
|
5145
|
-
result = await traceSpan(toolName, async (toolEmit) => {
|
|
5146
|
-
toolEmit("signature", `prompty.tool.${toolName}`);
|
|
5147
|
-
toolEmit("description", `Execute tool: ${toolName}`);
|
|
5148
|
-
toolEmit("inputs", { arguments: parsedArgs, tool_call_id: toolCallId });
|
|
5149
|
-
const r2 = await dispatchTool(toolName, parsedArgs, tools, agent ?? {}, parentInputs ?? {});
|
|
5150
|
-
toolEmit("result", r2);
|
|
5151
|
-
return r2;
|
|
5368
|
+
if (Array.isArray(choices) && choices.length > 0) {
|
|
5369
|
+
const choice = choices[0];
|
|
5370
|
+
const message = choice.message;
|
|
5371
|
+
if (message && Array.isArray(message.tool_calls)) {
|
|
5372
|
+
const toolCalls = message.tool_calls.map((tc) => {
|
|
5373
|
+
const fn = tc.function;
|
|
5374
|
+
return {
|
|
5375
|
+
id: tc.id,
|
|
5376
|
+
name: fn.name,
|
|
5377
|
+
arguments: fn.arguments
|
|
5378
|
+
};
|
|
5152
5379
|
});
|
|
5153
|
-
|
|
5154
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
5380
|
+
return { toolCalls, textContent: message.content ?? "" };
|
|
5155
5381
|
}
|
|
5156
|
-
toolInputs.push({ name: toolName, arguments: parsedArgs, tool_call_id: toolCallId, result });
|
|
5157
|
-
messages.push(
|
|
5158
|
-
new Message("tool", [text(result)], {
|
|
5159
|
-
tool_call_id: toolCallId,
|
|
5160
|
-
name: toolName
|
|
5161
|
-
})
|
|
5162
|
-
);
|
|
5163
|
-
}
|
|
5164
|
-
if (parentEmit) {
|
|
5165
|
-
parentEmit("inputs", { tool_calls: toolInputs });
|
|
5166
5382
|
}
|
|
5167
|
-
return
|
|
5383
|
+
return { toolCalls: [], textContent: "" };
|
|
5168
5384
|
}
|
|
5169
|
-
async function
|
|
5170
|
-
const
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
const toolName = block.name;
|
|
5181
|
-
const toolCallId = block.id;
|
|
5182
|
-
let toolArgs = block.input;
|
|
5183
|
-
if (agent && parentInputs && typeof toolArgs === "object" && toolArgs !== null && !Array.isArray(toolArgs)) {
|
|
5184
|
-
toolArgs = resolveBindings(agent, toolName, toolArgs, parentInputs);
|
|
5185
|
-
}
|
|
5186
|
-
let result;
|
|
5385
|
+
async function dispatchOneToolWithExtensions(tc, tools, agent, parentInputs, ext) {
|
|
5386
|
+
const { onEvent, signal, guardrails } = ext;
|
|
5387
|
+
try {
|
|
5388
|
+
checkCancellation(signal);
|
|
5389
|
+
} catch (err) {
|
|
5390
|
+
emitEvent(onEvent, "cancelled", {});
|
|
5391
|
+
throw err;
|
|
5392
|
+
}
|
|
5393
|
+
emitEvent(onEvent, "tool_call_start", { name: tc.name, arguments: tc.arguments });
|
|
5394
|
+
if (guardrails) {
|
|
5395
|
+
let parsedArgs2 = {};
|
|
5187
5396
|
try {
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5397
|
+
const parsed = JSON.parse(tc.arguments);
|
|
5398
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
5399
|
+
parsedArgs2 = parsed;
|
|
5400
|
+
}
|
|
5401
|
+
} catch {
|
|
5402
|
+
}
|
|
5403
|
+
const gr = guardrails.checkTool(tc.name, parsedArgs2);
|
|
5404
|
+
if (!gr.allowed) {
|
|
5405
|
+
const deniedMsg = `Tool denied by guardrail: ${gr.reason}`;
|
|
5406
|
+
emitEvent(onEvent, "tool_result", { name: tc.name, result: deniedMsg });
|
|
5407
|
+
return deniedMsg;
|
|
5408
|
+
}
|
|
5409
|
+
if (gr.rewrite !== void 0) {
|
|
5410
|
+
tc = { ...tc, arguments: typeof gr.rewrite === "string" ? gr.rewrite : JSON.stringify(gr.rewrite) };
|
|
5198
5411
|
}
|
|
5199
|
-
toolInputs.push({ name: toolName, arguments: toolArgs, tool_use_id: toolCallId, result });
|
|
5200
|
-
toolResultBlocks.push({
|
|
5201
|
-
type: "tool_result",
|
|
5202
|
-
tool_use_id: toolCallId,
|
|
5203
|
-
content: result
|
|
5204
|
-
});
|
|
5205
5412
|
}
|
|
5206
|
-
|
|
5207
|
-
|
|
5413
|
+
let result;
|
|
5414
|
+
let parsedArgs;
|
|
5415
|
+
try {
|
|
5416
|
+
parsedArgs = JSON.parse(tc.arguments);
|
|
5417
|
+
if (agent && parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
5418
|
+
parsedArgs = resolveBindings(agent, tc.name, parsedArgs, parentInputs);
|
|
5419
|
+
}
|
|
5420
|
+
result = await traceSpan(tc.name, async (toolEmit) => {
|
|
5421
|
+
toolEmit("signature", `prompty.tool.${tc.name}`);
|
|
5422
|
+
toolEmit("description", `Execute tool: ${tc.name}`);
|
|
5423
|
+
toolEmit("inputs", { arguments: parsedArgs, id: tc.id });
|
|
5424
|
+
const r = await dispatchTool(tc.name, parsedArgs, tools, agent, parentInputs);
|
|
5425
|
+
toolEmit("result", r);
|
|
5426
|
+
return r;
|
|
5427
|
+
});
|
|
5428
|
+
} catch (err) {
|
|
5429
|
+
if (err instanceof CancelledError) throw err;
|
|
5430
|
+
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
5208
5431
|
}
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
);
|
|
5212
|
-
return messages;
|
|
5432
|
+
emitEvent(onEvent, "tool_result", { name: tc.name, result });
|
|
5433
|
+
return result;
|
|
5213
5434
|
}
|
|
5214
|
-
async function
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
const toolInputs = [];
|
|
5219
|
-
for (const fc of funcCalls) {
|
|
5220
|
-
const toolName = fc.name;
|
|
5221
|
-
const callId = fc.call_id ?? fc.id ?? "";
|
|
5222
|
-
const argsStr = fc.arguments ?? "{}";
|
|
5223
|
-
messages.push(
|
|
5224
|
-
new Message("assistant", [], {
|
|
5225
|
-
responses_function_call: {
|
|
5226
|
-
type: "function_call",
|
|
5227
|
-
call_id: callId,
|
|
5228
|
-
name: toolName,
|
|
5229
|
-
arguments: argsStr
|
|
5230
|
-
}
|
|
5231
|
-
})
|
|
5232
|
-
);
|
|
5233
|
-
let result;
|
|
5234
|
-
let parsedArgs;
|
|
5235
|
-
try {
|
|
5236
|
-
parsedArgs = JSON.parse(argsStr);
|
|
5237
|
-
if (agent && parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
5238
|
-
parsedArgs = resolveBindings(agent, toolName, parsedArgs, parentInputs);
|
|
5239
|
-
}
|
|
5240
|
-
result = await traceSpan(toolName, async (toolEmit) => {
|
|
5241
|
-
toolEmit("signature", `prompty.tool.${toolName}`);
|
|
5242
|
-
toolEmit("description", `Execute tool: ${toolName}`);
|
|
5243
|
-
toolEmit("inputs", { arguments: parsedArgs, call_id: callId });
|
|
5244
|
-
const r2 = await dispatchTool(toolName, parsedArgs, tools, agent ?? {}, parentInputs ?? {});
|
|
5245
|
-
toolEmit("result", r2);
|
|
5246
|
-
return r2;
|
|
5247
|
-
});
|
|
5248
|
-
} catch (err) {
|
|
5249
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
5250
|
-
}
|
|
5251
|
-
toolInputs.push({ name: toolName, arguments: parsedArgs, call_id: callId, result });
|
|
5252
|
-
messages.push(
|
|
5253
|
-
new Message("tool", [text(result)], {
|
|
5254
|
-
tool_call_id: callId,
|
|
5255
|
-
name: toolName
|
|
5256
|
-
})
|
|
5435
|
+
async function dispatchToolsWithExtensions(toolCalls, tools, agent, parentInputs, ext) {
|
|
5436
|
+
if (ext.parallel && toolCalls.length > 1) {
|
|
5437
|
+
return Promise.all(
|
|
5438
|
+
toolCalls.map((tc) => dispatchOneToolWithExtensions(tc, tools, agent, parentInputs, ext))
|
|
5257
5439
|
);
|
|
5258
5440
|
}
|
|
5441
|
+
const results = [];
|
|
5442
|
+
for (const tc of toolCalls) {
|
|
5443
|
+
results.push(await dispatchOneToolWithExtensions(tc, tools, agent, parentInputs, ext));
|
|
5444
|
+
}
|
|
5445
|
+
return results;
|
|
5446
|
+
}
|
|
5447
|
+
async function buildToolResultMessagesWithExtensions(response, tools, agent, parentInputs, parentEmit, ext) {
|
|
5448
|
+
const { toolCalls, textContent } = extractToolInfo(response);
|
|
5449
|
+
const toolResults = await dispatchToolsWithExtensions(toolCalls, tools, agent, parentInputs, ext);
|
|
5450
|
+
if (parentEmit) {
|
|
5451
|
+
parentEmit("inputs", {
|
|
5452
|
+
tool_calls: toolCalls.map((tc, i) => ({ name: tc.name, arguments: tc.arguments, id: tc.id, result: toolResults[i] }))
|
|
5453
|
+
});
|
|
5454
|
+
}
|
|
5455
|
+
const provider = resolveProvider(agent);
|
|
5456
|
+
const executor = getExecutor(provider);
|
|
5457
|
+
return executor.formatToolMessages(response, toolCalls, toolResults, textContent);
|
|
5458
|
+
}
|
|
5459
|
+
async function buildToolMessagesFromCallsWithExtensions(toolCalls, textContent, tools, agent, parentInputs, parentEmit, ext) {
|
|
5460
|
+
const normalizedCalls = toolCalls.map((tc) => ({ id: tc.id, name: tc.name, arguments: tc.arguments }));
|
|
5461
|
+
const toolResults = await dispatchToolsWithExtensions(normalizedCalls, tools, agent, parentInputs, ext);
|
|
5259
5462
|
if (parentEmit) {
|
|
5260
|
-
parentEmit("inputs", {
|
|
5463
|
+
parentEmit("inputs", {
|
|
5464
|
+
tool_calls: normalizedCalls.map((tc, i) => ({ name: tc.name, arguments: tc.arguments, id: tc.id, result: toolResults[i] }))
|
|
5465
|
+
});
|
|
5261
5466
|
}
|
|
5262
|
-
|
|
5467
|
+
const provider = resolveProvider(agent);
|
|
5468
|
+
const executor = getExecutor(provider);
|
|
5469
|
+
return executor.formatToolMessages(null, normalizedCalls, toolResults, textContent);
|
|
5263
5470
|
}
|
|
5264
|
-
var DEFAULT_FORMAT, DEFAULT_PARSER, DEFAULT_PROVIDER, DEFAULT_MAX_ITERATIONS
|
|
5471
|
+
var DEFAULT_FORMAT, DEFAULT_PARSER, DEFAULT_PROVIDER, DEFAULT_MAX_ITERATIONS;
|
|
5265
5472
|
var init_pipeline = __esm({
|
|
5266
5473
|
"src/core/pipeline.ts"() {
|
|
5267
5474
|
"use strict";
|
|
@@ -5271,11 +5478,15 @@ var init_pipeline = __esm({
|
|
|
5271
5478
|
init_tracer();
|
|
5272
5479
|
init_loader();
|
|
5273
5480
|
init_tool_dispatch();
|
|
5481
|
+
init_agent_events();
|
|
5482
|
+
init_cancellation();
|
|
5483
|
+
init_context2();
|
|
5484
|
+
init_guardrails();
|
|
5485
|
+
init_structured();
|
|
5274
5486
|
DEFAULT_FORMAT = "nunjucks";
|
|
5275
5487
|
DEFAULT_PARSER = "prompty";
|
|
5276
5488
|
DEFAULT_PROVIDER = "openai";
|
|
5277
5489
|
DEFAULT_MAX_ITERATIONS = 10;
|
|
5278
|
-
runAgent = executeAgent;
|
|
5279
5490
|
}
|
|
5280
5491
|
});
|
|
5281
5492
|
|
|
@@ -5287,11 +5498,14 @@ __export(index_exports, {
|
|
|
5287
5498
|
ApiKeyConnection: () => ApiKeyConnection,
|
|
5288
5499
|
ArrayProperty: () => ArrayProperty,
|
|
5289
5500
|
Binding: () => Binding,
|
|
5501
|
+
CancelledError: () => CancelledError,
|
|
5290
5502
|
Connection: () => Connection,
|
|
5291
5503
|
CustomTool: () => CustomTool,
|
|
5292
5504
|
FormatConfig: () => FormatConfig,
|
|
5293
5505
|
FoundryConnection: () => FoundryConnection,
|
|
5294
5506
|
FunctionTool: () => FunctionTool,
|
|
5507
|
+
GuardrailError: () => GuardrailError,
|
|
5508
|
+
Guardrails: () => Guardrails,
|
|
5295
5509
|
InvokerError: () => InvokerError,
|
|
5296
5510
|
LoadContext: () => LoadContext,
|
|
5297
5511
|
McpApprovalMode: () => McpApprovalMode,
|
|
@@ -5317,22 +5531,31 @@ __export(index_exports, {
|
|
|
5317
5531
|
ReferenceConnection: () => ReferenceConnection,
|
|
5318
5532
|
RemoteConnection: () => RemoteConnection,
|
|
5319
5533
|
SaveContext: () => SaveContext,
|
|
5534
|
+
Steering: () => Steering,
|
|
5535
|
+
StructuredResultSymbol: () => StructuredResultSymbol,
|
|
5320
5536
|
Template: () => Template,
|
|
5321
5537
|
ThreadMarker: () => ThreadMarker,
|
|
5322
5538
|
Tool: () => Tool,
|
|
5323
5539
|
Tracer: () => Tracer,
|
|
5540
|
+
bindTools: () => bindTools,
|
|
5541
|
+
cast: () => cast,
|
|
5542
|
+
checkCancellation: () => checkCancellation,
|
|
5324
5543
|
clearCache: () => clearCache,
|
|
5325
5544
|
clearConnections: () => clearConnections,
|
|
5326
5545
|
consoleTracer: () => consoleTracer,
|
|
5546
|
+
createStructuredResult: () => createStructuredResult,
|
|
5327
5547
|
dictContentToPart: () => dictContentToPart,
|
|
5328
5548
|
dictToMessage: () => dictToMessage,
|
|
5329
|
-
|
|
5330
|
-
|
|
5549
|
+
emitEvent: () => emitEvent,
|
|
5550
|
+
estimateChars: () => estimateChars,
|
|
5331
5551
|
getConnection: () => getConnection,
|
|
5332
5552
|
getExecutor: () => getExecutor,
|
|
5333
5553
|
getParser: () => getParser,
|
|
5334
5554
|
getProcessor: () => getProcessor,
|
|
5335
5555
|
getRenderer: () => getRenderer,
|
|
5556
|
+
invoke: () => invoke,
|
|
5557
|
+
invokeAgent: () => invokeAgent,
|
|
5558
|
+
isStructuredResult: () => isStructuredResult,
|
|
5336
5559
|
load: () => load,
|
|
5337
5560
|
otelTracer: () => otelTracer,
|
|
5338
5561
|
parse: () => parse,
|
|
@@ -5346,14 +5569,16 @@ __export(index_exports, {
|
|
|
5346
5569
|
render: () => render,
|
|
5347
5570
|
resolveBindings: () => resolveBindings,
|
|
5348
5571
|
run: () => run,
|
|
5349
|
-
runAgent: () => runAgent,
|
|
5350
5572
|
sanitizeValue: () => sanitizeValue,
|
|
5573
|
+
summarizeDropped: () => summarizeDropped,
|
|
5351
5574
|
text: () => text,
|
|
5352
5575
|
textMessage: () => textMessage,
|
|
5353
5576
|
toSerializable: () => toSerializable,
|
|
5577
|
+
tool: () => tool,
|
|
5354
5578
|
trace: () => trace,
|
|
5355
5579
|
traceMethod: () => traceMethod,
|
|
5356
5580
|
traceSpan: () => traceSpan,
|
|
5581
|
+
trimToContextWindow: () => trimToContextWindow,
|
|
5357
5582
|
validateInputs: () => validateInputs
|
|
5358
5583
|
});
|
|
5359
5584
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -5384,6 +5609,101 @@ function clearConnections() {
|
|
|
5384
5609
|
init_loader();
|
|
5385
5610
|
init_pipeline();
|
|
5386
5611
|
init_tool_dispatch();
|
|
5612
|
+
init_agent_events();
|
|
5613
|
+
init_cancellation();
|
|
5614
|
+
init_context2();
|
|
5615
|
+
init_guardrails();
|
|
5616
|
+
|
|
5617
|
+
// src/core/steering.ts
|
|
5618
|
+
init_types();
|
|
5619
|
+
var Steering = class {
|
|
5620
|
+
queue = [];
|
|
5621
|
+
/** Enqueue a message to be injected at the next iteration. */
|
|
5622
|
+
send(message) {
|
|
5623
|
+
this.queue.push(message);
|
|
5624
|
+
}
|
|
5625
|
+
/** Remove and return all queued messages as Message objects. */
|
|
5626
|
+
drain() {
|
|
5627
|
+
const items = this.queue.splice(0);
|
|
5628
|
+
return items.map((text2) => new Message("user", [{ kind: "text", value: text2 }]));
|
|
5629
|
+
}
|
|
5630
|
+
/** Whether there are pending messages without consuming them. */
|
|
5631
|
+
get hasPending() {
|
|
5632
|
+
return this.queue.length > 0;
|
|
5633
|
+
}
|
|
5634
|
+
};
|
|
5635
|
+
|
|
5636
|
+
// src/core/tool-decorator.ts
|
|
5637
|
+
init_tool();
|
|
5638
|
+
init_property();
|
|
5639
|
+
init_tool_dispatch();
|
|
5640
|
+
function tool(fn, options) {
|
|
5641
|
+
const toolName = options?.name ?? fn.name;
|
|
5642
|
+
const toolDesc = options?.description ?? "";
|
|
5643
|
+
const shouldRegister = options?.register !== false;
|
|
5644
|
+
const properties = (options?.parameters ?? []).map(
|
|
5645
|
+
(p) => new Property({
|
|
5646
|
+
name: p.name,
|
|
5647
|
+
kind: p.kind ?? "string",
|
|
5648
|
+
required: p.required ?? p.default === void 0,
|
|
5649
|
+
description: p.description,
|
|
5650
|
+
default: p.default
|
|
5651
|
+
})
|
|
5652
|
+
);
|
|
5653
|
+
const toolDef = new FunctionTool({
|
|
5654
|
+
name: toolName,
|
|
5655
|
+
kind: "function",
|
|
5656
|
+
description: toolDesc,
|
|
5657
|
+
parameters: properties
|
|
5658
|
+
});
|
|
5659
|
+
const wrapped = fn;
|
|
5660
|
+
wrapped.__tool__ = toolDef;
|
|
5661
|
+
if (shouldRegister) {
|
|
5662
|
+
registerTool(toolName, fn);
|
|
5663
|
+
}
|
|
5664
|
+
return wrapped;
|
|
5665
|
+
}
|
|
5666
|
+
function bindTools(agent, tools) {
|
|
5667
|
+
const handlers = {};
|
|
5668
|
+
for (const fn of tools) {
|
|
5669
|
+
const toolDef = fn.__tool__;
|
|
5670
|
+
if (!toolDef) {
|
|
5671
|
+
throw new Error(
|
|
5672
|
+
`Function '${fn.name || "(anonymous)"}' is not a tool()-wrapped function (missing __tool__ property)`
|
|
5673
|
+
);
|
|
5674
|
+
}
|
|
5675
|
+
const name = toolDef.name;
|
|
5676
|
+
if (name in handlers) {
|
|
5677
|
+
throw new Error(`Duplicate tool handler: '${name}'`);
|
|
5678
|
+
}
|
|
5679
|
+
handlers[name] = fn;
|
|
5680
|
+
}
|
|
5681
|
+
const declaredFunctionTools = /* @__PURE__ */ new Set();
|
|
5682
|
+
for (const toolDef of agent.tools ?? []) {
|
|
5683
|
+
if (toolDef.kind === "function") {
|
|
5684
|
+
declaredFunctionTools.add(toolDef.name);
|
|
5685
|
+
}
|
|
5686
|
+
}
|
|
5687
|
+
for (const name of Object.keys(handlers)) {
|
|
5688
|
+
if (!declaredFunctionTools.has(name)) {
|
|
5689
|
+
const declared = [...declaredFunctionTools].sort().join(", ") || "(none)";
|
|
5690
|
+
throw new Error(
|
|
5691
|
+
`Tool handler '${name}' has no matching 'kind: function' declaration in agent.tools. Declared function tools: ${declared}`
|
|
5692
|
+
);
|
|
5693
|
+
}
|
|
5694
|
+
}
|
|
5695
|
+
for (const name of declaredFunctionTools) {
|
|
5696
|
+
if (!(name in handlers)) {
|
|
5697
|
+
console.warn(
|
|
5698
|
+
`Tool '${name}' is declared in agent.tools but no handler was provided to bindTools()`
|
|
5699
|
+
);
|
|
5700
|
+
}
|
|
5701
|
+
}
|
|
5702
|
+
return handlers;
|
|
5703
|
+
}
|
|
5704
|
+
|
|
5705
|
+
// src/core/index.ts
|
|
5706
|
+
init_structured();
|
|
5387
5707
|
|
|
5388
5708
|
// src/renderers/nunjucks.ts
|
|
5389
5709
|
var import_nunjucks = __toESM(require("nunjucks"), 1);
|
|
@@ -5777,11 +6097,14 @@ registerParser("prompty", new PromptyChatParser());
|
|
|
5777
6097
|
ApiKeyConnection,
|
|
5778
6098
|
ArrayProperty,
|
|
5779
6099
|
Binding,
|
|
6100
|
+
CancelledError,
|
|
5780
6101
|
Connection,
|
|
5781
6102
|
CustomTool,
|
|
5782
6103
|
FormatConfig,
|
|
5783
6104
|
FoundryConnection,
|
|
5784
6105
|
FunctionTool,
|
|
6106
|
+
GuardrailError,
|
|
6107
|
+
Guardrails,
|
|
5785
6108
|
InvokerError,
|
|
5786
6109
|
LoadContext,
|
|
5787
6110
|
McpApprovalMode,
|
|
@@ -5807,22 +6130,31 @@ registerParser("prompty", new PromptyChatParser());
|
|
|
5807
6130
|
ReferenceConnection,
|
|
5808
6131
|
RemoteConnection,
|
|
5809
6132
|
SaveContext,
|
|
6133
|
+
Steering,
|
|
6134
|
+
StructuredResultSymbol,
|
|
5810
6135
|
Template,
|
|
5811
6136
|
ThreadMarker,
|
|
5812
6137
|
Tool,
|
|
5813
6138
|
Tracer,
|
|
6139
|
+
bindTools,
|
|
6140
|
+
cast,
|
|
6141
|
+
checkCancellation,
|
|
5814
6142
|
clearCache,
|
|
5815
6143
|
clearConnections,
|
|
5816
6144
|
consoleTracer,
|
|
6145
|
+
createStructuredResult,
|
|
5817
6146
|
dictContentToPart,
|
|
5818
6147
|
dictToMessage,
|
|
5819
|
-
|
|
5820
|
-
|
|
6148
|
+
emitEvent,
|
|
6149
|
+
estimateChars,
|
|
5821
6150
|
getConnection,
|
|
5822
6151
|
getExecutor,
|
|
5823
6152
|
getParser,
|
|
5824
6153
|
getProcessor,
|
|
5825
6154
|
getRenderer,
|
|
6155
|
+
invoke,
|
|
6156
|
+
invokeAgent,
|
|
6157
|
+
isStructuredResult,
|
|
5826
6158
|
load,
|
|
5827
6159
|
otelTracer,
|
|
5828
6160
|
parse,
|
|
@@ -5836,14 +6168,16 @@ registerParser("prompty", new PromptyChatParser());
|
|
|
5836
6168
|
render,
|
|
5837
6169
|
resolveBindings,
|
|
5838
6170
|
run,
|
|
5839
|
-
runAgent,
|
|
5840
6171
|
sanitizeValue,
|
|
6172
|
+
summarizeDropped,
|
|
5841
6173
|
text,
|
|
5842
6174
|
textMessage,
|
|
5843
6175
|
toSerializable,
|
|
6176
|
+
tool,
|
|
5844
6177
|
trace,
|
|
5845
6178
|
traceMethod,
|
|
5846
6179
|
traceSpan,
|
|
6180
|
+
trimToContextWindow,
|
|
5847
6181
|
validateInputs
|
|
5848
6182
|
});
|
|
5849
6183
|
//# sourceMappingURL=index.cjs.map
|