@prompty/core 2.0.0-alpha.5 → 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 +574 -236
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +286 -6
- package/dist/index.d.ts +286 -6
- package/dist/index.js +559 -236
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -4499,6 +4499,9 @@ var init_common = __esm({
|
|
|
4499
4499
|
|
|
4500
4500
|
// src/core/tool-dispatch.ts
|
|
4501
4501
|
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
4502
|
+
function registerTool(name, handler) {
|
|
4503
|
+
nameRegistry.set(name, handler);
|
|
4504
|
+
}
|
|
4502
4505
|
function getTool(name) {
|
|
4503
4506
|
return nameRegistry.get(name);
|
|
4504
4507
|
}
|
|
@@ -4522,12 +4525,12 @@ async function dispatchTool(toolName, args, userTools, agent, parentInputs) {
|
|
|
4522
4525
|
const result = await registeredFn(args);
|
|
4523
4526
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
4524
4527
|
}
|
|
4525
|
-
const
|
|
4526
|
-
if (!
|
|
4528
|
+
const tool2 = agent.tools?.find((t) => t.name === toolName);
|
|
4529
|
+
if (!tool2) {
|
|
4527
4530
|
const available = Object.keys(userTools).sort().join(", ") || "(none)";
|
|
4528
4531
|
return `Error: tool "${toolName}" not found in userTools or agent.tools. Available user tools: ${available}`;
|
|
4529
4532
|
}
|
|
4530
|
-
const kind =
|
|
4533
|
+
const kind = tool2.kind || "*";
|
|
4531
4534
|
let handler;
|
|
4532
4535
|
try {
|
|
4533
4536
|
handler = getToolHandler(kind);
|
|
@@ -4539,7 +4542,7 @@ async function dispatchTool(toolName, args, userTools, agent, parentInputs) {
|
|
|
4539
4542
|
}
|
|
4540
4543
|
}
|
|
4541
4544
|
return await handler.executeTool(
|
|
4542
|
-
|
|
4545
|
+
tool2,
|
|
4543
4546
|
args,
|
|
4544
4547
|
agent,
|
|
4545
4548
|
parentInputs
|
|
@@ -4564,34 +4567,34 @@ var init_tool_dispatch = __esm({
|
|
|
4564
4567
|
nameRegistry = /* @__PURE__ */ new Map();
|
|
4565
4568
|
toolHandlers = /* @__PURE__ */ new Map();
|
|
4566
4569
|
FunctionToolHandler = class {
|
|
4567
|
-
async executeTool(
|
|
4568
|
-
const name =
|
|
4570
|
+
async executeTool(tool2, _args, _agent, _parentInputs) {
|
|
4571
|
+
const name = tool2.name ?? "unknown";
|
|
4569
4572
|
throw new Error(
|
|
4570
4573
|
`Function tool '${name}' declared but no callable provided. Pass it via tools: { '${name}': fn } in invokeAgent().`
|
|
4571
4574
|
);
|
|
4572
4575
|
}
|
|
4573
4576
|
};
|
|
4574
4577
|
PromptyToolHandler = class {
|
|
4575
|
-
async executeTool(
|
|
4578
|
+
async executeTool(tool2, args, agent, _parentInputs) {
|
|
4576
4579
|
const { load: load2 } = await Promise.resolve().then(() => (init_loader(), loader_exports));
|
|
4577
4580
|
const { prepare: prepare2, run: run2, invokeAgent: invokeAgent2 } = await Promise.resolve().then(() => (init_pipeline(), pipeline_exports));
|
|
4578
4581
|
const parentPath = (agent.metadata ?? {}).__source_path;
|
|
4579
4582
|
if (!parentPath) {
|
|
4580
|
-
return `Error: cannot resolve PromptyTool '${
|
|
4583
|
+
return `Error: cannot resolve PromptyTool '${tool2.name}': parent has no __source_path`;
|
|
4581
4584
|
}
|
|
4582
|
-
const childPath = resolve2(dirname2(parentPath),
|
|
4585
|
+
const childPath = resolve2(dirname2(parentPath), tool2.path);
|
|
4583
4586
|
const stack = (agent.metadata ?? {}).__prompty_tool_stack ?? [];
|
|
4584
4587
|
const normalizedChild = resolve2(childPath);
|
|
4585
4588
|
const visited = /* @__PURE__ */ new Set([...stack.map((p) => resolve2(p)), resolve2(parentPath)]);
|
|
4586
4589
|
if (visited.has(normalizedChild)) {
|
|
4587
4590
|
const chain = [...stack, parentPath, childPath].join(" \u2192 ");
|
|
4588
|
-
return `Error executing PromptyTool '${
|
|
4591
|
+
return `Error executing PromptyTool '${tool2.name}': circular reference detected: ${chain}`;
|
|
4589
4592
|
}
|
|
4590
4593
|
try {
|
|
4591
4594
|
const child = load2(childPath);
|
|
4592
4595
|
if (!child.metadata) child.metadata = {};
|
|
4593
4596
|
child.metadata.__prompty_tool_stack = [...stack, parentPath];
|
|
4594
|
-
const mode =
|
|
4597
|
+
const mode = tool2.mode ?? "single";
|
|
4595
4598
|
if (mode === "agentic") {
|
|
4596
4599
|
const result = await invokeAgent2(child, args);
|
|
4597
4600
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
@@ -4601,7 +4604,7 @@ var init_tool_dispatch = __esm({
|
|
|
4601
4604
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
4602
4605
|
}
|
|
4603
4606
|
} catch (err) {
|
|
4604
|
-
return `Error executing PromptyTool '${
|
|
4607
|
+
return `Error executing PromptyTool '${tool2.name}': ${err instanceof Error ? err.message : String(err)}`;
|
|
4605
4608
|
}
|
|
4606
4609
|
}
|
|
4607
4610
|
};
|
|
@@ -4628,6 +4631,205 @@ var init_tool_dispatch = __esm({
|
|
|
4628
4631
|
}
|
|
4629
4632
|
});
|
|
4630
4633
|
|
|
4634
|
+
// src/core/agent-events.ts
|
|
4635
|
+
function emitEvent(callback, eventType, data) {
|
|
4636
|
+
if (!callback) return;
|
|
4637
|
+
try {
|
|
4638
|
+
callback(eventType, data);
|
|
4639
|
+
} catch (err) {
|
|
4640
|
+
if (typeof globalThis.console?.debug === "function") {
|
|
4641
|
+
globalThis.console.debug(`Event callback error for ${eventType}:`, err);
|
|
4642
|
+
}
|
|
4643
|
+
}
|
|
4644
|
+
}
|
|
4645
|
+
var init_agent_events = __esm({
|
|
4646
|
+
"src/core/agent-events.ts"() {
|
|
4647
|
+
"use strict";
|
|
4648
|
+
}
|
|
4649
|
+
});
|
|
4650
|
+
|
|
4651
|
+
// src/core/cancellation.ts
|
|
4652
|
+
function checkCancellation(signal) {
|
|
4653
|
+
if (signal?.aborted) {
|
|
4654
|
+
throw new CancelledError();
|
|
4655
|
+
}
|
|
4656
|
+
}
|
|
4657
|
+
var CancelledError;
|
|
4658
|
+
var init_cancellation = __esm({
|
|
4659
|
+
"src/core/cancellation.ts"() {
|
|
4660
|
+
"use strict";
|
|
4661
|
+
CancelledError = class extends Error {
|
|
4662
|
+
constructor(message = "Agent loop cancelled") {
|
|
4663
|
+
super(message);
|
|
4664
|
+
this.name = "CancelledError";
|
|
4665
|
+
}
|
|
4666
|
+
};
|
|
4667
|
+
}
|
|
4668
|
+
});
|
|
4669
|
+
|
|
4670
|
+
// src/core/context.ts
|
|
4671
|
+
function estimateChars(messages) {
|
|
4672
|
+
let total = 0;
|
|
4673
|
+
for (const msg of messages) {
|
|
4674
|
+
total += msg.role.length + 4;
|
|
4675
|
+
for (const part of msg.parts) {
|
|
4676
|
+
if (part.kind === "text") {
|
|
4677
|
+
total += part.value.length;
|
|
4678
|
+
} else {
|
|
4679
|
+
total += 200;
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
const toolCalls = msg.metadata?.tool_calls;
|
|
4683
|
+
if (toolCalls) {
|
|
4684
|
+
total += JSON.stringify(toolCalls).length;
|
|
4685
|
+
}
|
|
4686
|
+
}
|
|
4687
|
+
return total;
|
|
4688
|
+
}
|
|
4689
|
+
function truncate(text2, maxLen = 200) {
|
|
4690
|
+
return text2.length <= maxLen ? text2 : text2.slice(0, maxLen) + "\u2026";
|
|
4691
|
+
}
|
|
4692
|
+
function summarizeDropped(messages) {
|
|
4693
|
+
const lines = [];
|
|
4694
|
+
for (const msg of messages) {
|
|
4695
|
+
const msgText = msg.text.trim();
|
|
4696
|
+
if (msg.role === "user" && msgText) {
|
|
4697
|
+
lines.push(`User asked: ${truncate(msgText)}`);
|
|
4698
|
+
} else if (msg.role === "assistant") {
|
|
4699
|
+
if (msgText) lines.push(`Assistant: ${truncate(msgText)}`);
|
|
4700
|
+
const toolCalls = msg.metadata?.tool_calls;
|
|
4701
|
+
if (Array.isArray(toolCalls)) {
|
|
4702
|
+
const names = toolCalls.map(
|
|
4703
|
+
(tc) => tc.name ?? (tc.function?.name ?? "?")
|
|
4704
|
+
);
|
|
4705
|
+
lines.push(` Called tools: ${names.join(", ")}`);
|
|
4706
|
+
}
|
|
4707
|
+
}
|
|
4708
|
+
}
|
|
4709
|
+
if (lines.length === 0) return "";
|
|
4710
|
+
let result = "[Context summary: ";
|
|
4711
|
+
for (const line of lines) {
|
|
4712
|
+
if (result.length + line.length > 4e3) {
|
|
4713
|
+
result += "\n... (older messages omitted)";
|
|
4714
|
+
break;
|
|
4715
|
+
}
|
|
4716
|
+
result += line + "\n";
|
|
4717
|
+
}
|
|
4718
|
+
return result.trimEnd() + "]";
|
|
4719
|
+
}
|
|
4720
|
+
function trimToContextWindow(messages, budgetChars) {
|
|
4721
|
+
if (estimateChars(messages) <= budgetChars) {
|
|
4722
|
+
return [0, []];
|
|
4723
|
+
}
|
|
4724
|
+
let systemEnd = 0;
|
|
4725
|
+
for (let i = 0; i < messages.length; i++) {
|
|
4726
|
+
if (messages[i].role !== "system") {
|
|
4727
|
+
systemEnd = i;
|
|
4728
|
+
break;
|
|
4729
|
+
}
|
|
4730
|
+
if (i === messages.length - 1) systemEnd = messages.length;
|
|
4731
|
+
}
|
|
4732
|
+
const systemMsgs = messages.slice(0, systemEnd);
|
|
4733
|
+
const rest = messages.slice(systemEnd);
|
|
4734
|
+
const summaryBudget = Math.min(5e3, Math.floor(budgetChars * 0.05));
|
|
4735
|
+
const dropped = [];
|
|
4736
|
+
while (estimateChars([...systemMsgs, ...rest]) > budgetChars - summaryBudget && rest.length > 2) {
|
|
4737
|
+
dropped.push(rest.shift());
|
|
4738
|
+
}
|
|
4739
|
+
const droppedCount = dropped.length;
|
|
4740
|
+
messages.length = 0;
|
|
4741
|
+
messages.push(...systemMsgs);
|
|
4742
|
+
if (droppedCount > 0) {
|
|
4743
|
+
const summaryText = summarizeDropped(dropped);
|
|
4744
|
+
if (summaryText) {
|
|
4745
|
+
messages.push(new Message("user", [{ kind: "text", value: summaryText }]));
|
|
4746
|
+
}
|
|
4747
|
+
}
|
|
4748
|
+
messages.push(...rest);
|
|
4749
|
+
return [droppedCount, dropped];
|
|
4750
|
+
}
|
|
4751
|
+
var init_context2 = __esm({
|
|
4752
|
+
"src/core/context.ts"() {
|
|
4753
|
+
"use strict";
|
|
4754
|
+
init_types();
|
|
4755
|
+
}
|
|
4756
|
+
});
|
|
4757
|
+
|
|
4758
|
+
// src/core/guardrails.ts
|
|
4759
|
+
var GuardrailError, Guardrails;
|
|
4760
|
+
var init_guardrails = __esm({
|
|
4761
|
+
"src/core/guardrails.ts"() {
|
|
4762
|
+
"use strict";
|
|
4763
|
+
GuardrailError = class extends Error {
|
|
4764
|
+
reason;
|
|
4765
|
+
constructor(reason) {
|
|
4766
|
+
super(`Guardrail denied: ${reason}`);
|
|
4767
|
+
this.name = "GuardrailError";
|
|
4768
|
+
this.reason = reason;
|
|
4769
|
+
}
|
|
4770
|
+
};
|
|
4771
|
+
Guardrails = class {
|
|
4772
|
+
inputHook;
|
|
4773
|
+
outputHook;
|
|
4774
|
+
toolHook;
|
|
4775
|
+
constructor(options) {
|
|
4776
|
+
this.inputHook = options?.input;
|
|
4777
|
+
this.outputHook = options?.output;
|
|
4778
|
+
this.toolHook = options?.tool;
|
|
4779
|
+
}
|
|
4780
|
+
checkInput(messages) {
|
|
4781
|
+
if (!this.inputHook) return { allowed: true };
|
|
4782
|
+
return this.inputHook(messages);
|
|
4783
|
+
}
|
|
4784
|
+
checkOutput(message) {
|
|
4785
|
+
if (!this.outputHook) return { allowed: true };
|
|
4786
|
+
return this.outputHook(message);
|
|
4787
|
+
}
|
|
4788
|
+
checkTool(name, args) {
|
|
4789
|
+
if (!this.toolHook) return { allowed: true };
|
|
4790
|
+
return this.toolHook(name, args);
|
|
4791
|
+
}
|
|
4792
|
+
};
|
|
4793
|
+
}
|
|
4794
|
+
});
|
|
4795
|
+
|
|
4796
|
+
// src/core/structured.ts
|
|
4797
|
+
function createStructuredResult(data, rawJson) {
|
|
4798
|
+
const result = { ...data };
|
|
4799
|
+
Object.defineProperty(result, StructuredResultSymbol, {
|
|
4800
|
+
value: rawJson,
|
|
4801
|
+
writable: false,
|
|
4802
|
+
enumerable: false,
|
|
4803
|
+
configurable: false
|
|
4804
|
+
});
|
|
4805
|
+
return result;
|
|
4806
|
+
}
|
|
4807
|
+
function isStructuredResult(value) {
|
|
4808
|
+
return typeof value === "object" && value !== null && StructuredResultSymbol in value;
|
|
4809
|
+
}
|
|
4810
|
+
function cast(result, validator) {
|
|
4811
|
+
let jsonStr;
|
|
4812
|
+
if (isStructuredResult(result)) {
|
|
4813
|
+
jsonStr = result[StructuredResultSymbol];
|
|
4814
|
+
} else if (typeof result === "string") {
|
|
4815
|
+
jsonStr = result;
|
|
4816
|
+
} else {
|
|
4817
|
+
jsonStr = JSON.stringify(result);
|
|
4818
|
+
}
|
|
4819
|
+
const parsed = JSON.parse(jsonStr);
|
|
4820
|
+
if (validator) {
|
|
4821
|
+
return validator(parsed);
|
|
4822
|
+
}
|
|
4823
|
+
return parsed;
|
|
4824
|
+
}
|
|
4825
|
+
var StructuredResultSymbol;
|
|
4826
|
+
var init_structured = __esm({
|
|
4827
|
+
"src/core/structured.ts"() {
|
|
4828
|
+
"use strict";
|
|
4829
|
+
StructuredResultSymbol = /* @__PURE__ */ Symbol("prompty.rawJson");
|
|
4830
|
+
}
|
|
4831
|
+
});
|
|
4832
|
+
|
|
4631
4833
|
// src/core/pipeline.ts
|
|
4632
4834
|
var pipeline_exports = {};
|
|
4633
4835
|
__export(pipeline_exports, {
|
|
@@ -4831,6 +5033,9 @@ async function invoke(prompt, inputs, options) {
|
|
|
4831
5033
|
const messages = await prepare(agent, inputs);
|
|
4832
5034
|
const result = await run(agent, messages, options);
|
|
4833
5035
|
emit("result", result);
|
|
5036
|
+
if (options?.validator) {
|
|
5037
|
+
return cast(result, options.validator);
|
|
5038
|
+
}
|
|
4834
5039
|
return result;
|
|
4835
5040
|
});
|
|
4836
5041
|
}
|
|
@@ -4852,7 +5057,7 @@ function isAsyncIterable(value) {
|
|
|
4852
5057
|
function isToolCallLike(item) {
|
|
4853
5058
|
return typeof item === "object" && item !== null && "id" in item && "name" in item && "arguments" in item;
|
|
4854
5059
|
}
|
|
4855
|
-
async function consumeStream(agent, response) {
|
|
5060
|
+
async function consumeStream(agent, response, onEvent) {
|
|
4856
5061
|
const processed = await process2(agent, response);
|
|
4857
5062
|
const toolCalls = [];
|
|
4858
5063
|
const textParts = [];
|
|
@@ -4862,96 +5067,17 @@ async function consumeStream(agent, response) {
|
|
|
4862
5067
|
toolCalls.push(item);
|
|
4863
5068
|
} else if (typeof item === "string") {
|
|
4864
5069
|
textParts.push(item);
|
|
5070
|
+
emitEvent(onEvent, "token", { token: item });
|
|
4865
5071
|
}
|
|
4866
5072
|
}
|
|
4867
5073
|
} else if (typeof processed === "string") {
|
|
4868
5074
|
textParts.push(processed);
|
|
5075
|
+
emitEvent(onEvent, "token", { token: processed });
|
|
4869
5076
|
}
|
|
4870
5077
|
return { toolCalls, content: textParts.join("") };
|
|
4871
5078
|
}
|
|
4872
|
-
async function buildToolMessagesFromCalls(toolCalls, textContent, tools, agent, parentInputs, parentEmit) {
|
|
4873
|
-
const provider = resolveProvider(agent);
|
|
4874
|
-
const apiType = agent.model?.apiType || "chat";
|
|
4875
|
-
const messages = [];
|
|
4876
|
-
const toolInputs = [];
|
|
4877
|
-
if (provider === "anthropic") {
|
|
4878
|
-
const rawContent = [];
|
|
4879
|
-
if (textContent) rawContent.push({ type: "text", text: textContent });
|
|
4880
|
-
for (const tc of toolCalls) {
|
|
4881
|
-
rawContent.push({
|
|
4882
|
-
type: "tool_use",
|
|
4883
|
-
id: tc.id,
|
|
4884
|
-
name: tc.name,
|
|
4885
|
-
input: JSON.parse(tc.arguments)
|
|
4886
|
-
});
|
|
4887
|
-
}
|
|
4888
|
-
messages.push(
|
|
4889
|
-
new Message("assistant", textContent ? [text(textContent)] : [], { content: rawContent })
|
|
4890
|
-
);
|
|
4891
|
-
} else if (apiType === "responses") {
|
|
4892
|
-
for (const tc of toolCalls) {
|
|
4893
|
-
messages.push(
|
|
4894
|
-
new Message("assistant", [], {
|
|
4895
|
-
responses_function_call: {
|
|
4896
|
-
type: "function_call",
|
|
4897
|
-
call_id: tc.id,
|
|
4898
|
-
name: tc.name,
|
|
4899
|
-
arguments: tc.arguments
|
|
4900
|
-
}
|
|
4901
|
-
})
|
|
4902
|
-
);
|
|
4903
|
-
}
|
|
4904
|
-
} else {
|
|
4905
|
-
const rawToolCalls = toolCalls.map((tc) => ({
|
|
4906
|
-
id: tc.id,
|
|
4907
|
-
type: "function",
|
|
4908
|
-
function: { name: tc.name, arguments: tc.arguments }
|
|
4909
|
-
}));
|
|
4910
|
-
messages.push(
|
|
4911
|
-
new Message("assistant", textContent ? [text(textContent)] : [], {
|
|
4912
|
-
tool_calls: rawToolCalls
|
|
4913
|
-
})
|
|
4914
|
-
);
|
|
4915
|
-
}
|
|
4916
|
-
const toolResultBlocks = [];
|
|
4917
|
-
for (const tc of toolCalls) {
|
|
4918
|
-
let result;
|
|
4919
|
-
let parsedArgs;
|
|
4920
|
-
try {
|
|
4921
|
-
parsedArgs = JSON.parse(tc.arguments);
|
|
4922
|
-
if (parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
4923
|
-
parsedArgs = resolveBindings(agent, tc.name, parsedArgs, parentInputs);
|
|
4924
|
-
}
|
|
4925
|
-
result = await traceSpan(tc.name, async (toolEmit) => {
|
|
4926
|
-
toolEmit("signature", `prompty.tool.${tc.name}`);
|
|
4927
|
-
toolEmit("description", `Execute tool: ${tc.name}`);
|
|
4928
|
-
toolEmit("inputs", { arguments: parsedArgs, id: tc.id });
|
|
4929
|
-
const r = await dispatchTool(tc.name, parsedArgs, tools, agent, parentInputs ?? {});
|
|
4930
|
-
toolEmit("result", r);
|
|
4931
|
-
return r;
|
|
4932
|
-
});
|
|
4933
|
-
} catch (err) {
|
|
4934
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
4935
|
-
}
|
|
4936
|
-
toolInputs.push({ name: tc.name, arguments: parsedArgs, id: tc.id, result });
|
|
4937
|
-
if (provider === "anthropic") {
|
|
4938
|
-
toolResultBlocks.push({ type: "tool_result", tool_use_id: tc.id, content: result });
|
|
4939
|
-
} else {
|
|
4940
|
-
messages.push(
|
|
4941
|
-
new Message("tool", [text(result)], { tool_call_id: tc.id, name: tc.name })
|
|
4942
|
-
);
|
|
4943
|
-
}
|
|
4944
|
-
}
|
|
4945
|
-
if (provider === "anthropic" && toolResultBlocks.length > 0) {
|
|
4946
|
-
messages.push(new Message("user", [], { tool_results: toolResultBlocks }));
|
|
4947
|
-
}
|
|
4948
|
-
if (parentEmit) {
|
|
4949
|
-
parentEmit("inputs", { tool_calls: toolInputs });
|
|
4950
|
-
}
|
|
4951
|
-
return messages;
|
|
4952
|
-
}
|
|
4953
5079
|
async function invokeAgent(prompt, inputs, options) {
|
|
4954
|
-
|
|
5080
|
+
const rawResult = await traceSpan("invokeAgent", async (emit) => {
|
|
4955
5081
|
const agent = typeof prompt === "string" ? await traceSpan("load", async (loadEmit) => {
|
|
4956
5082
|
loadEmit("signature", "prompty.load");
|
|
4957
5083
|
loadEmit("description", "Load a prompty file.");
|
|
@@ -4962,21 +5088,72 @@ async function invokeAgent(prompt, inputs, options) {
|
|
|
4962
5088
|
}) : prompt;
|
|
4963
5089
|
const tools = options?.tools ?? {};
|
|
4964
5090
|
const maxIterations = options?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
5091
|
+
const onEvent = options?.onEvent;
|
|
5092
|
+
const signal = options?.signal;
|
|
5093
|
+
const contextBudget = options?.contextBudget;
|
|
5094
|
+
const guardrails = options?.guardrails;
|
|
5095
|
+
const steering = options?.steering;
|
|
5096
|
+
const parallelToolCalls = options?.parallelToolCalls ?? false;
|
|
4965
5097
|
emit("signature", "prompty.invokeAgent");
|
|
4966
5098
|
emit("description", "Invoke a prompty with tool calling");
|
|
4967
5099
|
emit("inputs", { prompt: serializeAgent(agent), tools: Object.keys(tools), inputs: inputs ?? {} });
|
|
4968
|
-
|
|
5100
|
+
let messages = await prepare(agent, inputs);
|
|
4969
5101
|
const parentInputs = inputs ?? {};
|
|
4970
5102
|
const provider = resolveProvider(agent);
|
|
4971
5103
|
const executor = getExecutor(provider);
|
|
4972
|
-
let response =
|
|
5104
|
+
let response = null;
|
|
4973
5105
|
let iteration = 0;
|
|
4974
5106
|
while (true) {
|
|
5107
|
+
try {
|
|
5108
|
+
checkCancellation(signal);
|
|
5109
|
+
} catch (err) {
|
|
5110
|
+
emitEvent(onEvent, "cancelled", {});
|
|
5111
|
+
throw err;
|
|
5112
|
+
}
|
|
5113
|
+
if (steering) {
|
|
5114
|
+
const pending = steering.drain();
|
|
5115
|
+
if (pending.length > 0) {
|
|
5116
|
+
messages.push(...pending);
|
|
5117
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5118
|
+
emitEvent(onEvent, "status", { message: `Injected ${pending.length} steering message(s)` });
|
|
5119
|
+
}
|
|
5120
|
+
}
|
|
5121
|
+
if (contextBudget !== void 0) {
|
|
5122
|
+
const [droppedCount] = trimToContextWindow(messages, contextBudget);
|
|
5123
|
+
if (droppedCount > 0) {
|
|
5124
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5125
|
+
emitEvent(onEvent, "status", { message: `Trimmed ${droppedCount} messages for context budget` });
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5128
|
+
if (guardrails) {
|
|
5129
|
+
const result2 = guardrails.checkInput(messages);
|
|
5130
|
+
if (!result2.allowed) {
|
|
5131
|
+
emitEvent(onEvent, "error", { message: `Input guardrail denied: ${result2.reason}` });
|
|
5132
|
+
throw new GuardrailError(result2.reason ?? "Input guardrail denied");
|
|
5133
|
+
}
|
|
5134
|
+
if (result2.rewrite) messages = result2.rewrite;
|
|
5135
|
+
}
|
|
5136
|
+
try {
|
|
5137
|
+
checkCancellation(signal);
|
|
5138
|
+
} catch (err) {
|
|
5139
|
+
emitEvent(onEvent, "cancelled", {});
|
|
5140
|
+
throw err;
|
|
5141
|
+
}
|
|
5142
|
+
response = await executor.execute(agent, messages);
|
|
4975
5143
|
if (isAsyncIterable(response)) {
|
|
4976
|
-
const { toolCalls, content } = await consumeStream(agent, response);
|
|
5144
|
+
const { toolCalls, content } = await consumeStream(agent, response, onEvent);
|
|
5145
|
+
if (guardrails && content) {
|
|
5146
|
+
const assistantMsg = new Message("assistant", [text(content)]);
|
|
5147
|
+
const gr = guardrails.checkOutput(assistantMsg);
|
|
5148
|
+
if (!gr.allowed) {
|
|
5149
|
+
emitEvent(onEvent, "error", { message: `Output guardrail denied: ${gr.reason}` });
|
|
5150
|
+
throw new GuardrailError(gr.reason ?? "Output guardrail denied");
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
4977
5153
|
if (toolCalls.length === 0) {
|
|
4978
5154
|
emit("iterations", iteration);
|
|
4979
5155
|
emit("result", content);
|
|
5156
|
+
emitEvent(onEvent, "done", { response: content, messages });
|
|
4980
5157
|
return content;
|
|
4981
5158
|
}
|
|
4982
5159
|
iteration++;
|
|
@@ -4988,15 +5165,55 @@ async function invokeAgent(prompt, inputs, options) {
|
|
|
4988
5165
|
const toolMessages2 = await traceSpan("toolCalls", async (toolEmit) => {
|
|
4989
5166
|
toolEmit("signature", "prompty.invokeAgent.toolCalls");
|
|
4990
5167
|
toolEmit("description", `Tool call round ${iteration}`);
|
|
4991
|
-
const result2 = await
|
|
5168
|
+
const result2 = await buildToolMessagesFromCallsWithExtensions(
|
|
5169
|
+
toolCalls,
|
|
5170
|
+
content,
|
|
5171
|
+
tools,
|
|
5172
|
+
agent,
|
|
5173
|
+
parentInputs,
|
|
5174
|
+
toolEmit,
|
|
5175
|
+
{ onEvent, signal, guardrails, parallel: parallelToolCalls }
|
|
5176
|
+
);
|
|
4992
5177
|
toolEmit("result", result2.map((m) => ({ role: m.role, content: m.parts.map((p) => p.value ?? "").join(""), metadata: m.metadata })));
|
|
4993
5178
|
return result2;
|
|
4994
5179
|
});
|
|
4995
5180
|
messages.push(...toolMessages2);
|
|
4996
|
-
|
|
5181
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
4997
5182
|
continue;
|
|
4998
5183
|
}
|
|
4999
|
-
if (!hasToolCalls(response))
|
|
5184
|
+
if (!hasToolCalls(response)) {
|
|
5185
|
+
const finalResult = options?.raw ? response : await process2(agent, response);
|
|
5186
|
+
if (guardrails) {
|
|
5187
|
+
const contentStr = typeof finalResult === "string" ? finalResult : JSON.stringify(finalResult);
|
|
5188
|
+
const assistantMsg = new Message("assistant", [text(contentStr)]);
|
|
5189
|
+
const gr = guardrails.checkOutput(assistantMsg);
|
|
5190
|
+
if (!gr.allowed) {
|
|
5191
|
+
emitEvent(onEvent, "error", { message: `Output guardrail denied: ${gr.reason}` });
|
|
5192
|
+
throw new GuardrailError(gr.reason ?? "Output guardrail denied");
|
|
5193
|
+
}
|
|
5194
|
+
if (gr.rewrite !== void 0) {
|
|
5195
|
+
emit("iterations", iteration);
|
|
5196
|
+
emit("result", gr.rewrite);
|
|
5197
|
+
emitEvent(onEvent, "done", { response: gr.rewrite, messages });
|
|
5198
|
+
return gr.rewrite;
|
|
5199
|
+
}
|
|
5200
|
+
}
|
|
5201
|
+
emit("iterations", iteration);
|
|
5202
|
+
emit("result", finalResult);
|
|
5203
|
+
emitEvent(onEvent, "done", { response: finalResult, messages });
|
|
5204
|
+
return finalResult;
|
|
5205
|
+
}
|
|
5206
|
+
if (guardrails) {
|
|
5207
|
+
const { textContent } = extractToolInfo(response);
|
|
5208
|
+
if (textContent) {
|
|
5209
|
+
const assistantMsg = new Message("assistant", [text(textContent)]);
|
|
5210
|
+
const gr = guardrails.checkOutput(assistantMsg);
|
|
5211
|
+
if (!gr.allowed) {
|
|
5212
|
+
emitEvent(onEvent, "error", { message: `Output guardrail denied: ${gr.reason}` });
|
|
5213
|
+
throw new GuardrailError(gr.reason ?? "Output guardrail denied");
|
|
5214
|
+
}
|
|
5215
|
+
}
|
|
5216
|
+
}
|
|
5000
5217
|
iteration++;
|
|
5001
5218
|
if (iteration > maxIterations) {
|
|
5002
5219
|
throw new Error(
|
|
@@ -5006,22 +5223,35 @@ async function invokeAgent(prompt, inputs, options) {
|
|
|
5006
5223
|
const toolMessages = await traceSpan("toolCalls", async (toolEmit) => {
|
|
5007
5224
|
toolEmit("signature", "prompty.invokeAgent.toolCalls");
|
|
5008
5225
|
toolEmit("description", `Tool call round ${iteration}`);
|
|
5009
|
-
const result2 = await
|
|
5226
|
+
const result2 = await buildToolResultMessagesWithExtensions(
|
|
5227
|
+
response,
|
|
5228
|
+
tools,
|
|
5229
|
+
agent,
|
|
5230
|
+
parentInputs,
|
|
5231
|
+
toolEmit,
|
|
5232
|
+
{ onEvent, signal, guardrails, parallel: parallelToolCalls }
|
|
5233
|
+
);
|
|
5010
5234
|
toolEmit("result", result2.map((m) => ({ role: m.role, content: m.parts.map((p) => p.value ?? "").join(""), metadata: m.metadata })));
|
|
5011
5235
|
return result2;
|
|
5012
5236
|
});
|
|
5013
5237
|
messages.push(...toolMessages);
|
|
5014
|
-
|
|
5238
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5015
5239
|
}
|
|
5016
5240
|
emit("iterations", iteration);
|
|
5017
5241
|
if (options?.raw) {
|
|
5018
5242
|
emit("result", response);
|
|
5243
|
+
emitEvent(onEvent, "done", { response, messages });
|
|
5019
5244
|
return response;
|
|
5020
5245
|
}
|
|
5021
5246
|
const result = await process2(agent, response);
|
|
5022
5247
|
emit("result", result);
|
|
5248
|
+
emitEvent(onEvent, "done", { response: result, messages });
|
|
5023
5249
|
return result;
|
|
5024
5250
|
});
|
|
5251
|
+
if (options?.validator) {
|
|
5252
|
+
return cast(rawResult, options.validator);
|
|
5253
|
+
}
|
|
5254
|
+
return rawResult;
|
|
5025
5255
|
}
|
|
5026
5256
|
function expandThreads(messages, nonces, inputs) {
|
|
5027
5257
|
if (nonces.size === 0) return messages;
|
|
@@ -5090,158 +5320,136 @@ function hasToolCalls(response) {
|
|
|
5090
5320
|
}
|
|
5091
5321
|
return false;
|
|
5092
5322
|
}
|
|
5093
|
-
|
|
5323
|
+
function extractToolInfo(response) {
|
|
5324
|
+
if (typeof response !== "object" || response === null) {
|
|
5325
|
+
return { toolCalls: [], textContent: "" };
|
|
5326
|
+
}
|
|
5094
5327
|
const r = response;
|
|
5095
5328
|
if (Array.isArray(r.content) && r.stop_reason === "tool_use") {
|
|
5096
|
-
|
|
5329
|
+
const content = r.content;
|
|
5330
|
+
const toolCalls = content.filter((b) => b.type === "tool_use").map((b) => ({
|
|
5331
|
+
id: b.id,
|
|
5332
|
+
name: b.name,
|
|
5333
|
+
arguments: JSON.stringify(b.input)
|
|
5334
|
+
}));
|
|
5335
|
+
const textContent = content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
5336
|
+
return { toolCalls, textContent };
|
|
5097
5337
|
}
|
|
5098
5338
|
if (r.object === "response" && Array.isArray(r.output)) {
|
|
5099
|
-
|
|
5339
|
+
const funcCalls = r.output.filter(
|
|
5340
|
+
(item) => item.type === "function_call"
|
|
5341
|
+
);
|
|
5342
|
+
const toolCalls = funcCalls.map((fc) => ({
|
|
5343
|
+
id: fc.call_id ?? fc.id ?? "",
|
|
5344
|
+
call_id: fc.call_id ?? fc.id ?? "",
|
|
5345
|
+
name: fc.name,
|
|
5346
|
+
arguments: fc.arguments ?? "{}"
|
|
5347
|
+
}));
|
|
5348
|
+
return { toolCalls, textContent: "" };
|
|
5100
5349
|
}
|
|
5101
|
-
return buildOpenAIToolResultMessages(r, tools, agent, parentInputs, parentEmit);
|
|
5102
|
-
}
|
|
5103
|
-
async function buildOpenAIToolResultMessages(r, tools, agent, parentInputs, parentEmit) {
|
|
5104
5350
|
const choices = r.choices;
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
for (const tc of toolCalls) {
|
|
5117
|
-
const fn = tc.function;
|
|
5118
|
-
const toolName = fn.name;
|
|
5119
|
-
const toolCallId = tc.id;
|
|
5120
|
-
let result;
|
|
5121
|
-
let parsedArgs;
|
|
5122
|
-
try {
|
|
5123
|
-
parsedArgs = JSON.parse(fn.arguments);
|
|
5124
|
-
if (agent && parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
5125
|
-
parsedArgs = resolveBindings(agent, toolName, parsedArgs, parentInputs);
|
|
5126
|
-
}
|
|
5127
|
-
result = await traceSpan(toolName, async (toolEmit) => {
|
|
5128
|
-
toolEmit("signature", `prompty.tool.${toolName}`);
|
|
5129
|
-
toolEmit("description", `Execute tool: ${toolName}`);
|
|
5130
|
-
toolEmit("inputs", { arguments: parsedArgs, tool_call_id: toolCallId });
|
|
5131
|
-
const r2 = await dispatchTool(toolName, parsedArgs, tools, agent ?? {}, parentInputs ?? {});
|
|
5132
|
-
toolEmit("result", r2);
|
|
5133
|
-
return r2;
|
|
5351
|
+
if (Array.isArray(choices) && choices.length > 0) {
|
|
5352
|
+
const choice = choices[0];
|
|
5353
|
+
const message = choice.message;
|
|
5354
|
+
if (message && Array.isArray(message.tool_calls)) {
|
|
5355
|
+
const toolCalls = message.tool_calls.map((tc) => {
|
|
5356
|
+
const fn = tc.function;
|
|
5357
|
+
return {
|
|
5358
|
+
id: tc.id,
|
|
5359
|
+
name: fn.name,
|
|
5360
|
+
arguments: fn.arguments
|
|
5361
|
+
};
|
|
5134
5362
|
});
|
|
5135
|
-
|
|
5136
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
5363
|
+
return { toolCalls, textContent: message.content ?? "" };
|
|
5137
5364
|
}
|
|
5138
|
-
toolInputs.push({ name: toolName, arguments: parsedArgs, tool_call_id: toolCallId, result });
|
|
5139
|
-
messages.push(
|
|
5140
|
-
new Message("tool", [text(result)], {
|
|
5141
|
-
tool_call_id: toolCallId,
|
|
5142
|
-
name: toolName
|
|
5143
|
-
})
|
|
5144
|
-
);
|
|
5145
|
-
}
|
|
5146
|
-
if (parentEmit) {
|
|
5147
|
-
parentEmit("inputs", { tool_calls: toolInputs });
|
|
5148
5365
|
}
|
|
5149
|
-
return
|
|
5366
|
+
return { toolCalls: [], textContent: "" };
|
|
5150
5367
|
}
|
|
5151
|
-
async function
|
|
5152
|
-
const
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
const toolName = block.name;
|
|
5163
|
-
const toolCallId = block.id;
|
|
5164
|
-
let toolArgs = block.input;
|
|
5165
|
-
if (agent && parentInputs && typeof toolArgs === "object" && toolArgs !== null && !Array.isArray(toolArgs)) {
|
|
5166
|
-
toolArgs = resolveBindings(agent, toolName, toolArgs, parentInputs);
|
|
5167
|
-
}
|
|
5168
|
-
let result;
|
|
5368
|
+
async function dispatchOneToolWithExtensions(tc, tools, agent, parentInputs, ext) {
|
|
5369
|
+
const { onEvent, signal, guardrails } = ext;
|
|
5370
|
+
try {
|
|
5371
|
+
checkCancellation(signal);
|
|
5372
|
+
} catch (err) {
|
|
5373
|
+
emitEvent(onEvent, "cancelled", {});
|
|
5374
|
+
throw err;
|
|
5375
|
+
}
|
|
5376
|
+
emitEvent(onEvent, "tool_call_start", { name: tc.name, arguments: tc.arguments });
|
|
5377
|
+
if (guardrails) {
|
|
5378
|
+
let parsedArgs2 = {};
|
|
5169
5379
|
try {
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5380
|
+
const parsed = JSON.parse(tc.arguments);
|
|
5381
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
5382
|
+
parsedArgs2 = parsed;
|
|
5383
|
+
}
|
|
5384
|
+
} catch {
|
|
5385
|
+
}
|
|
5386
|
+
const gr = guardrails.checkTool(tc.name, parsedArgs2);
|
|
5387
|
+
if (!gr.allowed) {
|
|
5388
|
+
const deniedMsg = `Tool denied by guardrail: ${gr.reason}`;
|
|
5389
|
+
emitEvent(onEvent, "tool_result", { name: tc.name, result: deniedMsg });
|
|
5390
|
+
return deniedMsg;
|
|
5391
|
+
}
|
|
5392
|
+
if (gr.rewrite !== void 0) {
|
|
5393
|
+
tc = { ...tc, arguments: typeof gr.rewrite === "string" ? gr.rewrite : JSON.stringify(gr.rewrite) };
|
|
5180
5394
|
}
|
|
5181
|
-
toolInputs.push({ name: toolName, arguments: toolArgs, tool_use_id: toolCallId, result });
|
|
5182
|
-
toolResultBlocks.push({
|
|
5183
|
-
type: "tool_result",
|
|
5184
|
-
tool_use_id: toolCallId,
|
|
5185
|
-
content: result
|
|
5186
|
-
});
|
|
5187
5395
|
}
|
|
5188
|
-
|
|
5189
|
-
|
|
5396
|
+
let result;
|
|
5397
|
+
let parsedArgs;
|
|
5398
|
+
try {
|
|
5399
|
+
parsedArgs = JSON.parse(tc.arguments);
|
|
5400
|
+
if (agent && parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
5401
|
+
parsedArgs = resolveBindings(agent, tc.name, parsedArgs, parentInputs);
|
|
5402
|
+
}
|
|
5403
|
+
result = await traceSpan(tc.name, async (toolEmit) => {
|
|
5404
|
+
toolEmit("signature", `prompty.tool.${tc.name}`);
|
|
5405
|
+
toolEmit("description", `Execute tool: ${tc.name}`);
|
|
5406
|
+
toolEmit("inputs", { arguments: parsedArgs, id: tc.id });
|
|
5407
|
+
const r = await dispatchTool(tc.name, parsedArgs, tools, agent, parentInputs);
|
|
5408
|
+
toolEmit("result", r);
|
|
5409
|
+
return r;
|
|
5410
|
+
});
|
|
5411
|
+
} catch (err) {
|
|
5412
|
+
if (err instanceof CancelledError) throw err;
|
|
5413
|
+
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
5190
5414
|
}
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
);
|
|
5194
|
-
return messages;
|
|
5415
|
+
emitEvent(onEvent, "tool_result", { name: tc.name, result });
|
|
5416
|
+
return result;
|
|
5195
5417
|
}
|
|
5196
|
-
async function
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
const toolInputs = [];
|
|
5201
|
-
for (const fc of funcCalls) {
|
|
5202
|
-
const toolName = fc.name;
|
|
5203
|
-
const callId = fc.call_id ?? fc.id ?? "";
|
|
5204
|
-
const argsStr = fc.arguments ?? "{}";
|
|
5205
|
-
messages.push(
|
|
5206
|
-
new Message("assistant", [], {
|
|
5207
|
-
responses_function_call: {
|
|
5208
|
-
type: "function_call",
|
|
5209
|
-
call_id: callId,
|
|
5210
|
-
name: toolName,
|
|
5211
|
-
arguments: argsStr
|
|
5212
|
-
}
|
|
5213
|
-
})
|
|
5214
|
-
);
|
|
5215
|
-
let result;
|
|
5216
|
-
let parsedArgs;
|
|
5217
|
-
try {
|
|
5218
|
-
parsedArgs = JSON.parse(argsStr);
|
|
5219
|
-
if (agent && parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
5220
|
-
parsedArgs = resolveBindings(agent, toolName, parsedArgs, parentInputs);
|
|
5221
|
-
}
|
|
5222
|
-
result = await traceSpan(toolName, async (toolEmit) => {
|
|
5223
|
-
toolEmit("signature", `prompty.tool.${toolName}`);
|
|
5224
|
-
toolEmit("description", `Execute tool: ${toolName}`);
|
|
5225
|
-
toolEmit("inputs", { arguments: parsedArgs, call_id: callId });
|
|
5226
|
-
const r2 = await dispatchTool(toolName, parsedArgs, tools, agent ?? {}, parentInputs ?? {});
|
|
5227
|
-
toolEmit("result", r2);
|
|
5228
|
-
return r2;
|
|
5229
|
-
});
|
|
5230
|
-
} catch (err) {
|
|
5231
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
5232
|
-
}
|
|
5233
|
-
toolInputs.push({ name: toolName, arguments: parsedArgs, call_id: callId, result });
|
|
5234
|
-
messages.push(
|
|
5235
|
-
new Message("tool", [text(result)], {
|
|
5236
|
-
tool_call_id: callId,
|
|
5237
|
-
name: toolName
|
|
5238
|
-
})
|
|
5418
|
+
async function dispatchToolsWithExtensions(toolCalls, tools, agent, parentInputs, ext) {
|
|
5419
|
+
if (ext.parallel && toolCalls.length > 1) {
|
|
5420
|
+
return Promise.all(
|
|
5421
|
+
toolCalls.map((tc) => dispatchOneToolWithExtensions(tc, tools, agent, parentInputs, ext))
|
|
5239
5422
|
);
|
|
5240
5423
|
}
|
|
5424
|
+
const results = [];
|
|
5425
|
+
for (const tc of toolCalls) {
|
|
5426
|
+
results.push(await dispatchOneToolWithExtensions(tc, tools, agent, parentInputs, ext));
|
|
5427
|
+
}
|
|
5428
|
+
return results;
|
|
5429
|
+
}
|
|
5430
|
+
async function buildToolResultMessagesWithExtensions(response, tools, agent, parentInputs, parentEmit, ext) {
|
|
5431
|
+
const { toolCalls, textContent } = extractToolInfo(response);
|
|
5432
|
+
const toolResults = await dispatchToolsWithExtensions(toolCalls, tools, agent, parentInputs, ext);
|
|
5433
|
+
if (parentEmit) {
|
|
5434
|
+
parentEmit("inputs", {
|
|
5435
|
+
tool_calls: toolCalls.map((tc, i) => ({ name: tc.name, arguments: tc.arguments, id: tc.id, result: toolResults[i] }))
|
|
5436
|
+
});
|
|
5437
|
+
}
|
|
5438
|
+
const provider = resolveProvider(agent);
|
|
5439
|
+
const executor = getExecutor(provider);
|
|
5440
|
+
return executor.formatToolMessages(response, toolCalls, toolResults, textContent);
|
|
5441
|
+
}
|
|
5442
|
+
async function buildToolMessagesFromCallsWithExtensions(toolCalls, textContent, tools, agent, parentInputs, parentEmit, ext) {
|
|
5443
|
+
const normalizedCalls = toolCalls.map((tc) => ({ id: tc.id, name: tc.name, arguments: tc.arguments }));
|
|
5444
|
+
const toolResults = await dispatchToolsWithExtensions(normalizedCalls, tools, agent, parentInputs, ext);
|
|
5241
5445
|
if (parentEmit) {
|
|
5242
|
-
parentEmit("inputs", {
|
|
5446
|
+
parentEmit("inputs", {
|
|
5447
|
+
tool_calls: normalizedCalls.map((tc, i) => ({ name: tc.name, arguments: tc.arguments, id: tc.id, result: toolResults[i] }))
|
|
5448
|
+
});
|
|
5243
5449
|
}
|
|
5244
|
-
|
|
5450
|
+
const provider = resolveProvider(agent);
|
|
5451
|
+
const executor = getExecutor(provider);
|
|
5452
|
+
return executor.formatToolMessages(null, normalizedCalls, toolResults, textContent);
|
|
5245
5453
|
}
|
|
5246
5454
|
var DEFAULT_FORMAT, DEFAULT_PARSER, DEFAULT_PROVIDER, DEFAULT_MAX_ITERATIONS;
|
|
5247
5455
|
var init_pipeline = __esm({
|
|
@@ -5253,6 +5461,11 @@ var init_pipeline = __esm({
|
|
|
5253
5461
|
init_tracer();
|
|
5254
5462
|
init_loader();
|
|
5255
5463
|
init_tool_dispatch();
|
|
5464
|
+
init_agent_events();
|
|
5465
|
+
init_cancellation();
|
|
5466
|
+
init_context2();
|
|
5467
|
+
init_guardrails();
|
|
5468
|
+
init_structured();
|
|
5256
5469
|
DEFAULT_FORMAT = "nunjucks";
|
|
5257
5470
|
DEFAULT_PARSER = "prompty";
|
|
5258
5471
|
DEFAULT_PROVIDER = "openai";
|
|
@@ -5286,6 +5499,101 @@ function clearConnections() {
|
|
|
5286
5499
|
init_loader();
|
|
5287
5500
|
init_pipeline();
|
|
5288
5501
|
init_tool_dispatch();
|
|
5502
|
+
init_agent_events();
|
|
5503
|
+
init_cancellation();
|
|
5504
|
+
init_context2();
|
|
5505
|
+
init_guardrails();
|
|
5506
|
+
|
|
5507
|
+
// src/core/steering.ts
|
|
5508
|
+
init_types();
|
|
5509
|
+
var Steering = class {
|
|
5510
|
+
queue = [];
|
|
5511
|
+
/** Enqueue a message to be injected at the next iteration. */
|
|
5512
|
+
send(message) {
|
|
5513
|
+
this.queue.push(message);
|
|
5514
|
+
}
|
|
5515
|
+
/** Remove and return all queued messages as Message objects. */
|
|
5516
|
+
drain() {
|
|
5517
|
+
const items = this.queue.splice(0);
|
|
5518
|
+
return items.map((text2) => new Message("user", [{ kind: "text", value: text2 }]));
|
|
5519
|
+
}
|
|
5520
|
+
/** Whether there are pending messages without consuming them. */
|
|
5521
|
+
get hasPending() {
|
|
5522
|
+
return this.queue.length > 0;
|
|
5523
|
+
}
|
|
5524
|
+
};
|
|
5525
|
+
|
|
5526
|
+
// src/core/tool-decorator.ts
|
|
5527
|
+
init_tool();
|
|
5528
|
+
init_property();
|
|
5529
|
+
init_tool_dispatch();
|
|
5530
|
+
function tool(fn, options) {
|
|
5531
|
+
const toolName = options?.name ?? fn.name;
|
|
5532
|
+
const toolDesc = options?.description ?? "";
|
|
5533
|
+
const shouldRegister = options?.register !== false;
|
|
5534
|
+
const properties = (options?.parameters ?? []).map(
|
|
5535
|
+
(p) => new Property({
|
|
5536
|
+
name: p.name,
|
|
5537
|
+
kind: p.kind ?? "string",
|
|
5538
|
+
required: p.required ?? p.default === void 0,
|
|
5539
|
+
description: p.description,
|
|
5540
|
+
default: p.default
|
|
5541
|
+
})
|
|
5542
|
+
);
|
|
5543
|
+
const toolDef = new FunctionTool({
|
|
5544
|
+
name: toolName,
|
|
5545
|
+
kind: "function",
|
|
5546
|
+
description: toolDesc,
|
|
5547
|
+
parameters: properties
|
|
5548
|
+
});
|
|
5549
|
+
const wrapped = fn;
|
|
5550
|
+
wrapped.__tool__ = toolDef;
|
|
5551
|
+
if (shouldRegister) {
|
|
5552
|
+
registerTool(toolName, fn);
|
|
5553
|
+
}
|
|
5554
|
+
return wrapped;
|
|
5555
|
+
}
|
|
5556
|
+
function bindTools(agent, tools) {
|
|
5557
|
+
const handlers = {};
|
|
5558
|
+
for (const fn of tools) {
|
|
5559
|
+
const toolDef = fn.__tool__;
|
|
5560
|
+
if (!toolDef) {
|
|
5561
|
+
throw new Error(
|
|
5562
|
+
`Function '${fn.name || "(anonymous)"}' is not a tool()-wrapped function (missing __tool__ property)`
|
|
5563
|
+
);
|
|
5564
|
+
}
|
|
5565
|
+
const name = toolDef.name;
|
|
5566
|
+
if (name in handlers) {
|
|
5567
|
+
throw new Error(`Duplicate tool handler: '${name}'`);
|
|
5568
|
+
}
|
|
5569
|
+
handlers[name] = fn;
|
|
5570
|
+
}
|
|
5571
|
+
const declaredFunctionTools = /* @__PURE__ */ new Set();
|
|
5572
|
+
for (const toolDef of agent.tools ?? []) {
|
|
5573
|
+
if (toolDef.kind === "function") {
|
|
5574
|
+
declaredFunctionTools.add(toolDef.name);
|
|
5575
|
+
}
|
|
5576
|
+
}
|
|
5577
|
+
for (const name of Object.keys(handlers)) {
|
|
5578
|
+
if (!declaredFunctionTools.has(name)) {
|
|
5579
|
+
const declared = [...declaredFunctionTools].sort().join(", ") || "(none)";
|
|
5580
|
+
throw new Error(
|
|
5581
|
+
`Tool handler '${name}' has no matching 'kind: function' declaration in agent.tools. Declared function tools: ${declared}`
|
|
5582
|
+
);
|
|
5583
|
+
}
|
|
5584
|
+
}
|
|
5585
|
+
for (const name of declaredFunctionTools) {
|
|
5586
|
+
if (!(name in handlers)) {
|
|
5587
|
+
console.warn(
|
|
5588
|
+
`Tool '${name}' is declared in agent.tools but no handler was provided to bindTools()`
|
|
5589
|
+
);
|
|
5590
|
+
}
|
|
5591
|
+
}
|
|
5592
|
+
return handlers;
|
|
5593
|
+
}
|
|
5594
|
+
|
|
5595
|
+
// src/core/index.ts
|
|
5596
|
+
init_structured();
|
|
5289
5597
|
|
|
5290
5598
|
// src/renderers/nunjucks.ts
|
|
5291
5599
|
init_common();
|
|
@@ -5678,11 +5986,14 @@ export {
|
|
|
5678
5986
|
ApiKeyConnection,
|
|
5679
5987
|
ArrayProperty,
|
|
5680
5988
|
Binding,
|
|
5989
|
+
CancelledError,
|
|
5681
5990
|
Connection,
|
|
5682
5991
|
CustomTool,
|
|
5683
5992
|
FormatConfig,
|
|
5684
5993
|
FoundryConnection,
|
|
5685
5994
|
FunctionTool,
|
|
5995
|
+
GuardrailError,
|
|
5996
|
+
Guardrails,
|
|
5686
5997
|
InvokerError,
|
|
5687
5998
|
LoadContext,
|
|
5688
5999
|
McpApprovalMode,
|
|
@@ -5708,15 +6019,23 @@ export {
|
|
|
5708
6019
|
ReferenceConnection,
|
|
5709
6020
|
RemoteConnection,
|
|
5710
6021
|
SaveContext,
|
|
6022
|
+
Steering,
|
|
6023
|
+
StructuredResultSymbol,
|
|
5711
6024
|
Template,
|
|
5712
6025
|
ThreadMarker,
|
|
5713
6026
|
Tool,
|
|
5714
6027
|
Tracer,
|
|
6028
|
+
bindTools,
|
|
6029
|
+
cast,
|
|
6030
|
+
checkCancellation,
|
|
5715
6031
|
clearCache,
|
|
5716
6032
|
clearConnections,
|
|
5717
6033
|
consoleTracer,
|
|
6034
|
+
createStructuredResult,
|
|
5718
6035
|
dictContentToPart,
|
|
5719
6036
|
dictToMessage,
|
|
6037
|
+
emitEvent,
|
|
6038
|
+
estimateChars,
|
|
5720
6039
|
getConnection,
|
|
5721
6040
|
getExecutor,
|
|
5722
6041
|
getParser,
|
|
@@ -5724,6 +6043,7 @@ export {
|
|
|
5724
6043
|
getRenderer,
|
|
5725
6044
|
invoke,
|
|
5726
6045
|
invokeAgent,
|
|
6046
|
+
isStructuredResult,
|
|
5727
6047
|
load,
|
|
5728
6048
|
otelTracer,
|
|
5729
6049
|
parse,
|
|
@@ -5738,12 +6058,15 @@ export {
|
|
|
5738
6058
|
resolveBindings,
|
|
5739
6059
|
run,
|
|
5740
6060
|
sanitizeValue,
|
|
6061
|
+
summarizeDropped,
|
|
5741
6062
|
text,
|
|
5742
6063
|
textMessage,
|
|
5743
6064
|
toSerializable,
|
|
6065
|
+
tool,
|
|
5744
6066
|
trace,
|
|
5745
6067
|
traceMethod,
|
|
5746
6068
|
traceSpan,
|
|
6069
|
+
trimToContextWindow,
|
|
5747
6070
|
validateInputs
|
|
5748
6071
|
};
|
|
5749
6072
|
//# sourceMappingURL=index.js.map
|