@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.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,34 +4584,34 @@ 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
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
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
4616
|
const result = await invokeAgent2(child, args);
|
|
4614
4617
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
@@ -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,6 +4648,205 @@ 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, {
|
|
@@ -4848,6 +5050,9 @@ async function invoke(prompt, inputs, options) {
|
|
|
4848
5050
|
const messages = await prepare(agent, inputs);
|
|
4849
5051
|
const result = await run(agent, messages, options);
|
|
4850
5052
|
emit("result", result);
|
|
5053
|
+
if (options?.validator) {
|
|
5054
|
+
return cast(result, options.validator);
|
|
5055
|
+
}
|
|
4851
5056
|
return result;
|
|
4852
5057
|
});
|
|
4853
5058
|
}
|
|
@@ -4869,7 +5074,7 @@ function isAsyncIterable(value) {
|
|
|
4869
5074
|
function isToolCallLike(item) {
|
|
4870
5075
|
return typeof item === "object" && item !== null && "id" in item && "name" in item && "arguments" in item;
|
|
4871
5076
|
}
|
|
4872
|
-
async function consumeStream(agent, response) {
|
|
5077
|
+
async function consumeStream(agent, response, onEvent) {
|
|
4873
5078
|
const processed = await process2(agent, response);
|
|
4874
5079
|
const toolCalls = [];
|
|
4875
5080
|
const textParts = [];
|
|
@@ -4879,96 +5084,17 @@ async function consumeStream(agent, response) {
|
|
|
4879
5084
|
toolCalls.push(item);
|
|
4880
5085
|
} else if (typeof item === "string") {
|
|
4881
5086
|
textParts.push(item);
|
|
5087
|
+
emitEvent(onEvent, "token", { token: item });
|
|
4882
5088
|
}
|
|
4883
5089
|
}
|
|
4884
5090
|
} else if (typeof processed === "string") {
|
|
4885
5091
|
textParts.push(processed);
|
|
5092
|
+
emitEvent(onEvent, "token", { token: processed });
|
|
4886
5093
|
}
|
|
4887
5094
|
return { toolCalls, content: textParts.join("") };
|
|
4888
5095
|
}
|
|
4889
|
-
async function buildToolMessagesFromCalls(toolCalls, textContent, tools, agent, parentInputs, parentEmit) {
|
|
4890
|
-
const provider = resolveProvider(agent);
|
|
4891
|
-
const apiType = agent.model?.apiType || "chat";
|
|
4892
|
-
const messages = [];
|
|
4893
|
-
const toolInputs = [];
|
|
4894
|
-
if (provider === "anthropic") {
|
|
4895
|
-
const rawContent = [];
|
|
4896
|
-
if (textContent) rawContent.push({ type: "text", text: textContent });
|
|
4897
|
-
for (const tc of toolCalls) {
|
|
4898
|
-
rawContent.push({
|
|
4899
|
-
type: "tool_use",
|
|
4900
|
-
id: tc.id,
|
|
4901
|
-
name: tc.name,
|
|
4902
|
-
input: JSON.parse(tc.arguments)
|
|
4903
|
-
});
|
|
4904
|
-
}
|
|
4905
|
-
messages.push(
|
|
4906
|
-
new Message("assistant", textContent ? [text(textContent)] : [], { content: rawContent })
|
|
4907
|
-
);
|
|
4908
|
-
} else if (apiType === "responses") {
|
|
4909
|
-
for (const tc of toolCalls) {
|
|
4910
|
-
messages.push(
|
|
4911
|
-
new Message("assistant", [], {
|
|
4912
|
-
responses_function_call: {
|
|
4913
|
-
type: "function_call",
|
|
4914
|
-
call_id: tc.id,
|
|
4915
|
-
name: tc.name,
|
|
4916
|
-
arguments: tc.arguments
|
|
4917
|
-
}
|
|
4918
|
-
})
|
|
4919
|
-
);
|
|
4920
|
-
}
|
|
4921
|
-
} else {
|
|
4922
|
-
const rawToolCalls = toolCalls.map((tc) => ({
|
|
4923
|
-
id: tc.id,
|
|
4924
|
-
type: "function",
|
|
4925
|
-
function: { name: tc.name, arguments: tc.arguments }
|
|
4926
|
-
}));
|
|
4927
|
-
messages.push(
|
|
4928
|
-
new Message("assistant", textContent ? [text(textContent)] : [], {
|
|
4929
|
-
tool_calls: rawToolCalls
|
|
4930
|
-
})
|
|
4931
|
-
);
|
|
4932
|
-
}
|
|
4933
|
-
const toolResultBlocks = [];
|
|
4934
|
-
for (const tc of toolCalls) {
|
|
4935
|
-
let result;
|
|
4936
|
-
let parsedArgs;
|
|
4937
|
-
try {
|
|
4938
|
-
parsedArgs = JSON.parse(tc.arguments);
|
|
4939
|
-
if (parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
4940
|
-
parsedArgs = resolveBindings(agent, tc.name, parsedArgs, parentInputs);
|
|
4941
|
-
}
|
|
4942
|
-
result = await traceSpan(tc.name, async (toolEmit) => {
|
|
4943
|
-
toolEmit("signature", `prompty.tool.${tc.name}`);
|
|
4944
|
-
toolEmit("description", `Execute tool: ${tc.name}`);
|
|
4945
|
-
toolEmit("inputs", { arguments: parsedArgs, id: tc.id });
|
|
4946
|
-
const r = await dispatchTool(tc.name, parsedArgs, tools, agent, parentInputs ?? {});
|
|
4947
|
-
toolEmit("result", r);
|
|
4948
|
-
return r;
|
|
4949
|
-
});
|
|
4950
|
-
} catch (err) {
|
|
4951
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
4952
|
-
}
|
|
4953
|
-
toolInputs.push({ name: tc.name, arguments: parsedArgs, id: tc.id, result });
|
|
4954
|
-
if (provider === "anthropic") {
|
|
4955
|
-
toolResultBlocks.push({ type: "tool_result", tool_use_id: tc.id, content: result });
|
|
4956
|
-
} else {
|
|
4957
|
-
messages.push(
|
|
4958
|
-
new Message("tool", [text(result)], { tool_call_id: tc.id, name: tc.name })
|
|
4959
|
-
);
|
|
4960
|
-
}
|
|
4961
|
-
}
|
|
4962
|
-
if (provider === "anthropic" && toolResultBlocks.length > 0) {
|
|
4963
|
-
messages.push(new Message("user", [], { tool_results: toolResultBlocks }));
|
|
4964
|
-
}
|
|
4965
|
-
if (parentEmit) {
|
|
4966
|
-
parentEmit("inputs", { tool_calls: toolInputs });
|
|
4967
|
-
}
|
|
4968
|
-
return messages;
|
|
4969
|
-
}
|
|
4970
5096
|
async function invokeAgent(prompt, inputs, options) {
|
|
4971
|
-
|
|
5097
|
+
const rawResult = await traceSpan("invokeAgent", async (emit) => {
|
|
4972
5098
|
const agent = typeof prompt === "string" ? await traceSpan("load", async (loadEmit) => {
|
|
4973
5099
|
loadEmit("signature", "prompty.load");
|
|
4974
5100
|
loadEmit("description", "Load a prompty file.");
|
|
@@ -4979,21 +5105,72 @@ async function invokeAgent(prompt, inputs, options) {
|
|
|
4979
5105
|
}) : prompt;
|
|
4980
5106
|
const tools = options?.tools ?? {};
|
|
4981
5107
|
const maxIterations = options?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
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;
|
|
4982
5114
|
emit("signature", "prompty.invokeAgent");
|
|
4983
5115
|
emit("description", "Invoke a prompty with tool calling");
|
|
4984
5116
|
emit("inputs", { prompt: serializeAgent(agent), tools: Object.keys(tools), inputs: inputs ?? {} });
|
|
4985
|
-
|
|
5117
|
+
let messages = await prepare(agent, inputs);
|
|
4986
5118
|
const parentInputs = inputs ?? {};
|
|
4987
5119
|
const provider = resolveProvider(agent);
|
|
4988
5120
|
const executor = getExecutor(provider);
|
|
4989
|
-
let response =
|
|
5121
|
+
let response = null;
|
|
4990
5122
|
let iteration = 0;
|
|
4991
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);
|
|
4992
5160
|
if (isAsyncIterable(response)) {
|
|
4993
|
-
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
|
+
}
|
|
4994
5170
|
if (toolCalls.length === 0) {
|
|
4995
5171
|
emit("iterations", iteration);
|
|
4996
5172
|
emit("result", content);
|
|
5173
|
+
emitEvent(onEvent, "done", { response: content, messages });
|
|
4997
5174
|
return content;
|
|
4998
5175
|
}
|
|
4999
5176
|
iteration++;
|
|
@@ -5005,15 +5182,55 @@ async function invokeAgent(prompt, inputs, options) {
|
|
|
5005
5182
|
const toolMessages2 = await traceSpan("toolCalls", async (toolEmit) => {
|
|
5006
5183
|
toolEmit("signature", "prompty.invokeAgent.toolCalls");
|
|
5007
5184
|
toolEmit("description", `Tool call round ${iteration}`);
|
|
5008
|
-
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
|
+
);
|
|
5009
5194
|
toolEmit("result", result2.map((m) => ({ role: m.role, content: m.parts.map((p) => p.value ?? "").join(""), metadata: m.metadata })));
|
|
5010
5195
|
return result2;
|
|
5011
5196
|
});
|
|
5012
5197
|
messages.push(...toolMessages2);
|
|
5013
|
-
|
|
5198
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5014
5199
|
continue;
|
|
5015
5200
|
}
|
|
5016
|
-
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
|
+
}
|
|
5017
5234
|
iteration++;
|
|
5018
5235
|
if (iteration > maxIterations) {
|
|
5019
5236
|
throw new Error(
|
|
@@ -5023,22 +5240,35 @@ async function invokeAgent(prompt, inputs, options) {
|
|
|
5023
5240
|
const toolMessages = await traceSpan("toolCalls", async (toolEmit) => {
|
|
5024
5241
|
toolEmit("signature", "prompty.invokeAgent.toolCalls");
|
|
5025
5242
|
toolEmit("description", `Tool call round ${iteration}`);
|
|
5026
|
-
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
|
+
);
|
|
5027
5251
|
toolEmit("result", result2.map((m) => ({ role: m.role, content: m.parts.map((p) => p.value ?? "").join(""), metadata: m.metadata })));
|
|
5028
5252
|
return result2;
|
|
5029
5253
|
});
|
|
5030
5254
|
messages.push(...toolMessages);
|
|
5031
|
-
|
|
5255
|
+
emitEvent(onEvent, "messages_updated", { messages });
|
|
5032
5256
|
}
|
|
5033
5257
|
emit("iterations", iteration);
|
|
5034
5258
|
if (options?.raw) {
|
|
5035
5259
|
emit("result", response);
|
|
5260
|
+
emitEvent(onEvent, "done", { response, messages });
|
|
5036
5261
|
return response;
|
|
5037
5262
|
}
|
|
5038
5263
|
const result = await process2(agent, response);
|
|
5039
5264
|
emit("result", result);
|
|
5265
|
+
emitEvent(onEvent, "done", { response: result, messages });
|
|
5040
5266
|
return result;
|
|
5041
5267
|
});
|
|
5268
|
+
if (options?.validator) {
|
|
5269
|
+
return cast(rawResult, options.validator);
|
|
5270
|
+
}
|
|
5271
|
+
return rawResult;
|
|
5042
5272
|
}
|
|
5043
5273
|
function expandThreads(messages, nonces, inputs) {
|
|
5044
5274
|
if (nonces.size === 0) return messages;
|
|
@@ -5107,158 +5337,136 @@ function hasToolCalls(response) {
|
|
|
5107
5337
|
}
|
|
5108
5338
|
return false;
|
|
5109
5339
|
}
|
|
5110
|
-
|
|
5340
|
+
function extractToolInfo(response) {
|
|
5341
|
+
if (typeof response !== "object" || response === null) {
|
|
5342
|
+
return { toolCalls: [], textContent: "" };
|
|
5343
|
+
}
|
|
5111
5344
|
const r = response;
|
|
5112
5345
|
if (Array.isArray(r.content) && r.stop_reason === "tool_use") {
|
|
5113
|
-
|
|
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 };
|
|
5114
5354
|
}
|
|
5115
5355
|
if (r.object === "response" && Array.isArray(r.output)) {
|
|
5116
|
-
|
|
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: "" };
|
|
5117
5366
|
}
|
|
5118
|
-
return buildOpenAIToolResultMessages(r, tools, agent, parentInputs, parentEmit);
|
|
5119
|
-
}
|
|
5120
|
-
async function buildOpenAIToolResultMessages(r, tools, agent, parentInputs, parentEmit) {
|
|
5121
5367
|
const choices = r.choices;
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
for (const tc of toolCalls) {
|
|
5134
|
-
const fn = tc.function;
|
|
5135
|
-
const toolName = fn.name;
|
|
5136
|
-
const toolCallId = tc.id;
|
|
5137
|
-
let result;
|
|
5138
|
-
let parsedArgs;
|
|
5139
|
-
try {
|
|
5140
|
-
parsedArgs = JSON.parse(fn.arguments);
|
|
5141
|
-
if (agent && parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
5142
|
-
parsedArgs = resolveBindings(agent, toolName, parsedArgs, parentInputs);
|
|
5143
|
-
}
|
|
5144
|
-
result = await traceSpan(toolName, async (toolEmit) => {
|
|
5145
|
-
toolEmit("signature", `prompty.tool.${toolName}`);
|
|
5146
|
-
toolEmit("description", `Execute tool: ${toolName}`);
|
|
5147
|
-
toolEmit("inputs", { arguments: parsedArgs, tool_call_id: toolCallId });
|
|
5148
|
-
const r2 = await dispatchTool(toolName, parsedArgs, tools, agent ?? {}, parentInputs ?? {});
|
|
5149
|
-
toolEmit("result", r2);
|
|
5150
|
-
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
|
+
};
|
|
5151
5379
|
});
|
|
5152
|
-
|
|
5153
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
5380
|
+
return { toolCalls, textContent: message.content ?? "" };
|
|
5154
5381
|
}
|
|
5155
|
-
toolInputs.push({ name: toolName, arguments: parsedArgs, tool_call_id: toolCallId, result });
|
|
5156
|
-
messages.push(
|
|
5157
|
-
new Message("tool", [text(result)], {
|
|
5158
|
-
tool_call_id: toolCallId,
|
|
5159
|
-
name: toolName
|
|
5160
|
-
})
|
|
5161
|
-
);
|
|
5162
|
-
}
|
|
5163
|
-
if (parentEmit) {
|
|
5164
|
-
parentEmit("inputs", { tool_calls: toolInputs });
|
|
5165
5382
|
}
|
|
5166
|
-
return
|
|
5383
|
+
return { toolCalls: [], textContent: "" };
|
|
5167
5384
|
}
|
|
5168
|
-
async function
|
|
5169
|
-
const
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
const toolName = block.name;
|
|
5180
|
-
const toolCallId = block.id;
|
|
5181
|
-
let toolArgs = block.input;
|
|
5182
|
-
if (agent && parentInputs && typeof toolArgs === "object" && toolArgs !== null && !Array.isArray(toolArgs)) {
|
|
5183
|
-
toolArgs = resolveBindings(agent, toolName, toolArgs, parentInputs);
|
|
5184
|
-
}
|
|
5185
|
-
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 = {};
|
|
5186
5396
|
try {
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
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) };
|
|
5197
5411
|
}
|
|
5198
|
-
toolInputs.push({ name: toolName, arguments: toolArgs, tool_use_id: toolCallId, result });
|
|
5199
|
-
toolResultBlocks.push({
|
|
5200
|
-
type: "tool_result",
|
|
5201
|
-
tool_use_id: toolCallId,
|
|
5202
|
-
content: result
|
|
5203
|
-
});
|
|
5204
5412
|
}
|
|
5205
|
-
|
|
5206
|
-
|
|
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)}`;
|
|
5207
5431
|
}
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
);
|
|
5211
|
-
return messages;
|
|
5432
|
+
emitEvent(onEvent, "tool_result", { name: tc.name, result });
|
|
5433
|
+
return result;
|
|
5212
5434
|
}
|
|
5213
|
-
async function
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
const toolInputs = [];
|
|
5218
|
-
for (const fc of funcCalls) {
|
|
5219
|
-
const toolName = fc.name;
|
|
5220
|
-
const callId = fc.call_id ?? fc.id ?? "";
|
|
5221
|
-
const argsStr = fc.arguments ?? "{}";
|
|
5222
|
-
messages.push(
|
|
5223
|
-
new Message("assistant", [], {
|
|
5224
|
-
responses_function_call: {
|
|
5225
|
-
type: "function_call",
|
|
5226
|
-
call_id: callId,
|
|
5227
|
-
name: toolName,
|
|
5228
|
-
arguments: argsStr
|
|
5229
|
-
}
|
|
5230
|
-
})
|
|
5231
|
-
);
|
|
5232
|
-
let result;
|
|
5233
|
-
let parsedArgs;
|
|
5234
|
-
try {
|
|
5235
|
-
parsedArgs = JSON.parse(argsStr);
|
|
5236
|
-
if (agent && parentInputs && typeof parsedArgs === "object" && parsedArgs !== null && !Array.isArray(parsedArgs)) {
|
|
5237
|
-
parsedArgs = resolveBindings(agent, toolName, parsedArgs, parentInputs);
|
|
5238
|
-
}
|
|
5239
|
-
result = await traceSpan(toolName, async (toolEmit) => {
|
|
5240
|
-
toolEmit("signature", `prompty.tool.${toolName}`);
|
|
5241
|
-
toolEmit("description", `Execute tool: ${toolName}`);
|
|
5242
|
-
toolEmit("inputs", { arguments: parsedArgs, call_id: callId });
|
|
5243
|
-
const r2 = await dispatchTool(toolName, parsedArgs, tools, agent ?? {}, parentInputs ?? {});
|
|
5244
|
-
toolEmit("result", r2);
|
|
5245
|
-
return r2;
|
|
5246
|
-
});
|
|
5247
|
-
} catch (err) {
|
|
5248
|
-
result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
5249
|
-
}
|
|
5250
|
-
toolInputs.push({ name: toolName, arguments: parsedArgs, call_id: callId, result });
|
|
5251
|
-
messages.push(
|
|
5252
|
-
new Message("tool", [text(result)], {
|
|
5253
|
-
tool_call_id: callId,
|
|
5254
|
-
name: toolName
|
|
5255
|
-
})
|
|
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))
|
|
5256
5439
|
);
|
|
5257
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);
|
|
5258
5462
|
if (parentEmit) {
|
|
5259
|
-
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
|
+
});
|
|
5260
5466
|
}
|
|
5261
|
-
|
|
5467
|
+
const provider = resolveProvider(agent);
|
|
5468
|
+
const executor = getExecutor(provider);
|
|
5469
|
+
return executor.formatToolMessages(null, normalizedCalls, toolResults, textContent);
|
|
5262
5470
|
}
|
|
5263
5471
|
var DEFAULT_FORMAT, DEFAULT_PARSER, DEFAULT_PROVIDER, DEFAULT_MAX_ITERATIONS;
|
|
5264
5472
|
var init_pipeline = __esm({
|
|
@@ -5270,6 +5478,11 @@ var init_pipeline = __esm({
|
|
|
5270
5478
|
init_tracer();
|
|
5271
5479
|
init_loader();
|
|
5272
5480
|
init_tool_dispatch();
|
|
5481
|
+
init_agent_events();
|
|
5482
|
+
init_cancellation();
|
|
5483
|
+
init_context2();
|
|
5484
|
+
init_guardrails();
|
|
5485
|
+
init_structured();
|
|
5273
5486
|
DEFAULT_FORMAT = "nunjucks";
|
|
5274
5487
|
DEFAULT_PARSER = "prompty";
|
|
5275
5488
|
DEFAULT_PROVIDER = "openai";
|
|
@@ -5285,11 +5498,14 @@ __export(index_exports, {
|
|
|
5285
5498
|
ApiKeyConnection: () => ApiKeyConnection,
|
|
5286
5499
|
ArrayProperty: () => ArrayProperty,
|
|
5287
5500
|
Binding: () => Binding,
|
|
5501
|
+
CancelledError: () => CancelledError,
|
|
5288
5502
|
Connection: () => Connection,
|
|
5289
5503
|
CustomTool: () => CustomTool,
|
|
5290
5504
|
FormatConfig: () => FormatConfig,
|
|
5291
5505
|
FoundryConnection: () => FoundryConnection,
|
|
5292
5506
|
FunctionTool: () => FunctionTool,
|
|
5507
|
+
GuardrailError: () => GuardrailError,
|
|
5508
|
+
Guardrails: () => Guardrails,
|
|
5293
5509
|
InvokerError: () => InvokerError,
|
|
5294
5510
|
LoadContext: () => LoadContext,
|
|
5295
5511
|
McpApprovalMode: () => McpApprovalMode,
|
|
@@ -5315,15 +5531,23 @@ __export(index_exports, {
|
|
|
5315
5531
|
ReferenceConnection: () => ReferenceConnection,
|
|
5316
5532
|
RemoteConnection: () => RemoteConnection,
|
|
5317
5533
|
SaveContext: () => SaveContext,
|
|
5534
|
+
Steering: () => Steering,
|
|
5535
|
+
StructuredResultSymbol: () => StructuredResultSymbol,
|
|
5318
5536
|
Template: () => Template,
|
|
5319
5537
|
ThreadMarker: () => ThreadMarker,
|
|
5320
5538
|
Tool: () => Tool,
|
|
5321
5539
|
Tracer: () => Tracer,
|
|
5540
|
+
bindTools: () => bindTools,
|
|
5541
|
+
cast: () => cast,
|
|
5542
|
+
checkCancellation: () => checkCancellation,
|
|
5322
5543
|
clearCache: () => clearCache,
|
|
5323
5544
|
clearConnections: () => clearConnections,
|
|
5324
5545
|
consoleTracer: () => consoleTracer,
|
|
5546
|
+
createStructuredResult: () => createStructuredResult,
|
|
5325
5547
|
dictContentToPart: () => dictContentToPart,
|
|
5326
5548
|
dictToMessage: () => dictToMessage,
|
|
5549
|
+
emitEvent: () => emitEvent,
|
|
5550
|
+
estimateChars: () => estimateChars,
|
|
5327
5551
|
getConnection: () => getConnection,
|
|
5328
5552
|
getExecutor: () => getExecutor,
|
|
5329
5553
|
getParser: () => getParser,
|
|
@@ -5331,6 +5555,7 @@ __export(index_exports, {
|
|
|
5331
5555
|
getRenderer: () => getRenderer,
|
|
5332
5556
|
invoke: () => invoke,
|
|
5333
5557
|
invokeAgent: () => invokeAgent,
|
|
5558
|
+
isStructuredResult: () => isStructuredResult,
|
|
5334
5559
|
load: () => load,
|
|
5335
5560
|
otelTracer: () => otelTracer,
|
|
5336
5561
|
parse: () => parse,
|
|
@@ -5345,12 +5570,15 @@ __export(index_exports, {
|
|
|
5345
5570
|
resolveBindings: () => resolveBindings,
|
|
5346
5571
|
run: () => run,
|
|
5347
5572
|
sanitizeValue: () => sanitizeValue,
|
|
5573
|
+
summarizeDropped: () => summarizeDropped,
|
|
5348
5574
|
text: () => text,
|
|
5349
5575
|
textMessage: () => textMessage,
|
|
5350
5576
|
toSerializable: () => toSerializable,
|
|
5577
|
+
tool: () => tool,
|
|
5351
5578
|
trace: () => trace,
|
|
5352
5579
|
traceMethod: () => traceMethod,
|
|
5353
5580
|
traceSpan: () => traceSpan,
|
|
5581
|
+
trimToContextWindow: () => trimToContextWindow,
|
|
5354
5582
|
validateInputs: () => validateInputs
|
|
5355
5583
|
});
|
|
5356
5584
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -5381,6 +5609,101 @@ function clearConnections() {
|
|
|
5381
5609
|
init_loader();
|
|
5382
5610
|
init_pipeline();
|
|
5383
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();
|
|
5384
5707
|
|
|
5385
5708
|
// src/renderers/nunjucks.ts
|
|
5386
5709
|
var import_nunjucks = __toESM(require("nunjucks"), 1);
|
|
@@ -5774,11 +6097,14 @@ registerParser("prompty", new PromptyChatParser());
|
|
|
5774
6097
|
ApiKeyConnection,
|
|
5775
6098
|
ArrayProperty,
|
|
5776
6099
|
Binding,
|
|
6100
|
+
CancelledError,
|
|
5777
6101
|
Connection,
|
|
5778
6102
|
CustomTool,
|
|
5779
6103
|
FormatConfig,
|
|
5780
6104
|
FoundryConnection,
|
|
5781
6105
|
FunctionTool,
|
|
6106
|
+
GuardrailError,
|
|
6107
|
+
Guardrails,
|
|
5782
6108
|
InvokerError,
|
|
5783
6109
|
LoadContext,
|
|
5784
6110
|
McpApprovalMode,
|
|
@@ -5804,15 +6130,23 @@ registerParser("prompty", new PromptyChatParser());
|
|
|
5804
6130
|
ReferenceConnection,
|
|
5805
6131
|
RemoteConnection,
|
|
5806
6132
|
SaveContext,
|
|
6133
|
+
Steering,
|
|
6134
|
+
StructuredResultSymbol,
|
|
5807
6135
|
Template,
|
|
5808
6136
|
ThreadMarker,
|
|
5809
6137
|
Tool,
|
|
5810
6138
|
Tracer,
|
|
6139
|
+
bindTools,
|
|
6140
|
+
cast,
|
|
6141
|
+
checkCancellation,
|
|
5811
6142
|
clearCache,
|
|
5812
6143
|
clearConnections,
|
|
5813
6144
|
consoleTracer,
|
|
6145
|
+
createStructuredResult,
|
|
5814
6146
|
dictContentToPart,
|
|
5815
6147
|
dictToMessage,
|
|
6148
|
+
emitEvent,
|
|
6149
|
+
estimateChars,
|
|
5816
6150
|
getConnection,
|
|
5817
6151
|
getExecutor,
|
|
5818
6152
|
getParser,
|
|
@@ -5820,6 +6154,7 @@ registerParser("prompty", new PromptyChatParser());
|
|
|
5820
6154
|
getRenderer,
|
|
5821
6155
|
invoke,
|
|
5822
6156
|
invokeAgent,
|
|
6157
|
+
isStructuredResult,
|
|
5823
6158
|
load,
|
|
5824
6159
|
otelTracer,
|
|
5825
6160
|
parse,
|
|
@@ -5834,12 +6169,15 @@ registerParser("prompty", new PromptyChatParser());
|
|
|
5834
6169
|
resolveBindings,
|
|
5835
6170
|
run,
|
|
5836
6171
|
sanitizeValue,
|
|
6172
|
+
summarizeDropped,
|
|
5837
6173
|
text,
|
|
5838
6174
|
textMessage,
|
|
5839
6175
|
toSerializable,
|
|
6176
|
+
tool,
|
|
5840
6177
|
trace,
|
|
5841
6178
|
traceMethod,
|
|
5842
6179
|
traceSpan,
|
|
6180
|
+
trimToContextWindow,
|
|
5843
6181
|
validateInputs
|
|
5844
6182
|
});
|
|
5845
6183
|
//# sourceMappingURL=index.cjs.map
|