@aigne/agent-library 1.24.0 → 1.74.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -12
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/agent-skill-manager/index.cjs +30 -0
- package/dist/agent-skill-manager/index.d.cts +14 -0
- package/dist/agent-skill-manager/index.d.cts.map +1 -0
- package/dist/agent-skill-manager/index.d.mts +14 -0
- package/dist/agent-skill-manager/index.d.mts.map +1 -0
- package/dist/agent-skill-manager/index.mjs +30 -0
- package/dist/agent-skill-manager/index.mjs.map +1 -0
- package/{lib/esm/agent-skill-manager/prompt.js → dist/agent-skill-manager/prompt.cjs} +8 -3
- package/{lib/cjs/agent-skill-manager/prompt.js → dist/agent-skill-manager/prompt.mjs} +8 -6
- package/dist/agent-skill-manager/prompt.mjs.map +1 -0
- package/dist/ask-user-question/index.cjs +88 -0
- package/dist/ask-user-question/index.d.cts +33 -0
- package/dist/ask-user-question/index.d.cts.map +1 -0
- package/dist/ask-user-question/index.d.mts +33 -0
- package/dist/ask-user-question/index.d.mts.map +1 -0
- package/dist/ask-user-question/index.mjs +88 -0
- package/dist/ask-user-question/index.mjs.map +1 -0
- package/dist/bash/index.cjs +274 -0
- package/dist/bash/index.d.cts +184 -0
- package/dist/bash/index.d.cts.map +1 -0
- package/dist/bash/index.d.mts +184 -0
- package/dist/bash/index.d.mts.map +1 -0
- package/dist/bash/index.mjs +271 -0
- package/dist/bash/index.mjs.map +1 -0
- package/{lib/esm/bash/prompt.js → dist/bash/prompt.cjs} +6 -1
- package/{lib/cjs/bash/prompt.js → dist/bash/prompt.mjs} +6 -4
- package/dist/bash/prompt.mjs.map +1 -0
- package/dist/data-mapper/agents/mapper.cjs +62 -0
- package/dist/data-mapper/agents/mapper.mjs +62 -0
- package/dist/data-mapper/agents/mapper.mjs.map +1 -0
- package/dist/data-mapper/agents/reviewer.cjs +46 -0
- package/dist/data-mapper/agents/reviewer.mjs +46 -0
- package/dist/data-mapper/agents/reviewer.mjs.map +1 -0
- package/dist/data-mapper/index.cjs +25 -0
- package/dist/data-mapper/index.d.cts +26 -0
- package/dist/data-mapper/index.d.cts.map +1 -0
- package/dist/data-mapper/index.d.mts +26 -0
- package/dist/data-mapper/index.d.mts.map +1 -0
- package/dist/data-mapper/index.mjs +24 -0
- package/dist/data-mapper/index.mjs.map +1 -0
- package/{lib/esm/data-mapper/prompts.js → dist/data-mapper/prompts.cjs} +6 -1
- package/{lib/cjs/data-mapper/prompts.js → dist/data-mapper/prompts.mjs} +6 -4
- package/dist/data-mapper/prompts.mjs.map +1 -0
- package/dist/data-mapper/tools.cjs +119 -0
- package/dist/data-mapper/tools.d.cts +5 -0
- package/dist/data-mapper/tools.d.cts.map +1 -0
- package/dist/data-mapper/tools.d.mts +8 -0
- package/dist/data-mapper/tools.d.mts.map +1 -0
- package/dist/data-mapper/tools.mjs +117 -0
- package/dist/data-mapper/tools.mjs.map +1 -0
- package/dist/index.cjs +0 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/orchestrator/index.cjs +233 -0
- package/dist/orchestrator/index.d.cts +89 -0
- package/dist/orchestrator/index.d.cts.map +1 -0
- package/dist/orchestrator/index.d.mts +89 -0
- package/dist/orchestrator/index.d.mts.map +1 -0
- package/dist/orchestrator/index.mjs +230 -0
- package/dist/orchestrator/index.mjs.map +1 -0
- package/{lib/cjs/orchestrator/prompt.js → dist/orchestrator/prompt.cjs} +32 -28
- package/{lib/esm/orchestrator/prompt.js → dist/orchestrator/prompt.mjs} +30 -25
- package/dist/orchestrator/prompt.mjs.map +1 -0
- package/dist/orchestrator/type.cjs +74 -0
- package/dist/orchestrator/type.d.cts +27 -0
- package/dist/orchestrator/type.d.cts.map +1 -0
- package/dist/orchestrator/type.d.mts +27 -0
- package/dist/orchestrator/type.d.mts.map +1 -0
- package/dist/orchestrator/type.mjs +67 -0
- package/dist/orchestrator/type.mjs.map +1 -0
- package/dist/utils/fs.cjs +23 -0
- package/dist/utils/fs.d.cts +6 -0
- package/dist/utils/fs.d.cts.map +1 -0
- package/dist/utils/fs.d.mts +6 -0
- package/dist/utils/fs.d.mts.map +1 -0
- package/dist/utils/fs.mjs +22 -0
- package/dist/utils/fs.mjs.map +1 -0
- package/dist/utils/mutex.cjs +28 -0
- package/dist/utils/mutex.d.cts +10 -0
- package/dist/utils/mutex.d.cts.map +1 -0
- package/dist/utils/mutex.d.mts +10 -0
- package/dist/utils/mutex.d.mts.map +1 -0
- package/dist/utils/mutex.mjs +28 -0
- package/dist/utils/mutex.mjs.map +1 -0
- package/package.json +51 -35
- package/CHANGELOG.md +0 -2392
- package/lib/cjs/agent-skill-manager/index.d.ts +0 -10
- package/lib/cjs/agent-skill-manager/index.js +0 -26
- package/lib/cjs/agent-skill-manager/prompt.d.ts +0 -1
- package/lib/cjs/ask-user-question/index.d.ts +0 -28
- package/lib/cjs/ask-user-question/index.js +0 -108
- package/lib/cjs/bash/index.d.ts +0 -180
- package/lib/cjs/bash/index.js +0 -365
- package/lib/cjs/bash/prompt.d.ts +0 -1
- package/lib/cjs/data-mapper/agents/mapper.d.ts +0 -14
- package/lib/cjs/data-mapper/agents/mapper.js +0 -63
- package/lib/cjs/data-mapper/agents/reviewer.d.ts +0 -19
- package/lib/cjs/data-mapper/agents/reviewer.js +0 -47
- package/lib/cjs/data-mapper/index.d.ts +0 -18
- package/lib/cjs/data-mapper/index.js +0 -24
- package/lib/cjs/data-mapper/prompts.d.ts +0 -1
- package/lib/cjs/data-mapper/tools.d.ts +0 -11
- package/lib/cjs/data-mapper/tools.js +0 -164
- package/lib/cjs/index.d.ts +0 -1
- package/lib/cjs/index.js +0 -2
- package/lib/cjs/orchestrator/index.d.ts +0 -78
- package/lib/cjs/orchestrator/index.js +0 -277
- package/lib/cjs/orchestrator/prompt.d.ts +0 -3
- package/lib/cjs/orchestrator/type.d.ts +0 -388
- package/lib/cjs/orchestrator/type.js +0 -95
- package/lib/cjs/package.json +0 -3
- package/lib/cjs/utils/fs.d.ts +0 -2
- package/lib/cjs/utils/fs.js +0 -25
- package/lib/cjs/utils/mutex.d.ts +0 -6
- package/lib/cjs/utils/mutex.js +0 -28
- package/lib/dts/agent-skill-manager/index.d.ts +0 -10
- package/lib/dts/agent-skill-manager/prompt.d.ts +0 -1
- package/lib/dts/ask-user-question/index.d.ts +0 -28
- package/lib/dts/bash/index.d.ts +0 -180
- package/lib/dts/bash/prompt.d.ts +0 -1
- package/lib/dts/data-mapper/agents/mapper.d.ts +0 -14
- package/lib/dts/data-mapper/agents/reviewer.d.ts +0 -19
- package/lib/dts/data-mapper/index.d.ts +0 -18
- package/lib/dts/data-mapper/prompts.d.ts +0 -1
- package/lib/dts/data-mapper/tools.d.ts +0 -11
- package/lib/dts/index.d.ts +0 -1
- package/lib/dts/orchestrator/index.d.ts +0 -78
- package/lib/dts/orchestrator/prompt.d.ts +0 -3
- package/lib/dts/orchestrator/type.d.ts +0 -388
- package/lib/dts/utils/fs.d.ts +0 -2
- package/lib/dts/utils/mutex.d.ts +0 -6
- package/lib/esm/agent-skill-manager/index.d.ts +0 -10
- package/lib/esm/agent-skill-manager/index.js +0 -23
- package/lib/esm/agent-skill-manager/prompt.d.ts +0 -1
- package/lib/esm/ask-user-question/index.d.ts +0 -28
- package/lib/esm/ask-user-question/index.js +0 -105
- package/lib/esm/bash/index.d.ts +0 -180
- package/lib/esm/bash/index.js +0 -328
- package/lib/esm/bash/prompt.d.ts +0 -1
- package/lib/esm/data-mapper/agents/mapper.d.ts +0 -14
- package/lib/esm/data-mapper/agents/mapper.js +0 -61
- package/lib/esm/data-mapper/agents/reviewer.d.ts +0 -19
- package/lib/esm/data-mapper/agents/reviewer.js +0 -45
- package/lib/esm/data-mapper/index.d.ts +0 -18
- package/lib/esm/data-mapper/index.js +0 -16
- package/lib/esm/data-mapper/prompts.d.ts +0 -1
- package/lib/esm/data-mapper/tools.d.ts +0 -11
- package/lib/esm/data-mapper/tools.js +0 -155
- package/lib/esm/index.d.ts +0 -1
- package/lib/esm/index.js +0 -1
- package/lib/esm/orchestrator/index.d.ts +0 -78
- package/lib/esm/orchestrator/index.js +0 -240
- package/lib/esm/orchestrator/prompt.d.ts +0 -3
- package/lib/esm/orchestrator/type.d.ts +0 -388
- package/lib/esm/orchestrator/type.js +0 -89
- package/lib/esm/package.json +0 -3
- package/lib/esm/utils/fs.d.ts +0 -2
- package/lib/esm/utils/fs.js +0 -21
- package/lib/esm/utils/mutex.d.ts +0 -6
- package/lib/esm/utils/mutex.js +0 -24
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { AIGNE, UserInputTopic, UserOutputTopic } from "@aigne/core";
|
|
2
|
-
import mapper from "./agents/mapper.js";
|
|
3
|
-
import reviewer from "./agents/reviewer.js";
|
|
4
|
-
export async function generateMapping({ input, model, }) {
|
|
5
|
-
if (!model)
|
|
6
|
-
throw new Error("model is required to run data mapper");
|
|
7
|
-
const aigne = new AIGNE({ model, agents: [mapper, reviewer] });
|
|
8
|
-
aigne.publish(UserInputTopic, input);
|
|
9
|
-
const { message } = await aigne.subscribe(UserOutputTopic);
|
|
10
|
-
return {
|
|
11
|
-
jsonata: message.jsonata || "",
|
|
12
|
-
confidence: message.confidence || 0,
|
|
13
|
-
confidenceReasoning: message.confidenceReasoning || "",
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
export { applyJsonata } from "./tools.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const PROMPT_MAPPING = "You are an AI that generates JSONata mapping expressions to transform source data structures into target structures.\n\nGuidelines for creating JSONata mappings:\n\n1. Source References:\n - Use exact field paths from the source data, e.g. $.merchant_category\n - For accessing fields with names containing spaces, use backticks, e.g. $.`merchant category`\n - Jsonata will automatically extract all the fields from the current context. E.g. if you need all variants from all products, you can use $.products.variants. No need to do nested map reduce operations.\n - $. The variable with no name refers to the context value at any point in the input JSON hierarchy. E.g. if the current context is products.price, then $.currency is products.price.currency\n - %. The parent of the current context value. E.g. if the current context is products.variants.size and you want variant name, use %.name\n\n - When multiple source fields could map to a target, use a maximum of 3 fallbacks:\n GOOD: source1 ? source1 : source2 ? source2 : source3 ? source3 : 'default'\n BAD: source1 ? source1 : source1 ? source1 : source1 (repeated fields)\n\n2. Expression Rules:\n - Avoid unnecessary array/string operations\n - Each mapping should be clear and concise\n - Use proper JSONata syntax for coalesce operations\n - Do not use ~> to execute functions. Use the functions directly with the correct arguments or use $map(arr, $function) to apply a function to each element of an array.\n\n3. Array Handling:\n - For mapping to an array of objects, use the following patterns:\n a) When in array scope, use $.{} to map each object:\n Correct: [$.{\"id\": id, \"name\": name}]\n Incorrect: [{\"id\": $.id}]\n b) When outside array scope, include the source path:\n Correct: [$.items.{\"id\": id, \"name\": name}]\n Incorrect: [{\"id\": $.items.id}]\n c) For nested arrays, chain the array operators:\n Correct: [products.variants.{\"size\": size, \"color\": color}]\n Incorrect: [products.[{\"size\": variants.size}]]\n d) You need to use the square brackets [] to map to an array of objects, otherwise it might return an object and fail the validation.\n Correct: variants: [variants.{\"size\": size, \"color\": color}]\n Incorrect: variants: variants.{\"size\": variants.size}\n - For array elements, use JSONata array operators like [0] for first element, [-1] for last element\n - Square bracket notation [] can be used with predicates, e.g. items[type='book']\n\n4. Field Selection Priority:\n - Prefer variant-specific fields over general fields (e.g., sizeVariants.description over sizes)\n - Choose the most specific/detailed field available (e.g., type=\"shelf\" over category=\"furniture\")\n\n5. Filters:\n - Pay special attention to filter statements in the instruction and the schema description. Add them to the generated jsonata expression.\n Example: Get me all products with SKU 0406654608 or products: {\"type\": \"array\", description: \"only products with SKU 0406654608\"}\n Generated jsonata expression: Account.Order.Product[SKU = \"0406654608\"].{\"Description\": Description}\n - For filtering with arrays, you can use the \"in\" operator. E.g. library.books[\"Steven King\" in authors]\n\n6. Data Integrity:\n - ONLY use fields that exist in the source data structure\n - If no matching source field exists, leave the field undefined\n - Never invent or assume the existence of fields not present in the source data\n\n7. Function Calls:\n - You may use the following functions if prompted:\n $string(arg) - Converts argument to string\n $length(str) - Returns string length\n $substring(str, start[, length]) - Extracts substring\n $substringBefore(str, chars) - Gets substring before specified chars\n $substringAfter(str, chars) - Gets substring after specified chars\n $uppercase(str) - Converts to uppercase\n $lowercase(str) - Converts to lowercase\n $trim(str) - Removes whitespace from both ends\n $pad(str, width[, char]) - Pads string to specified width\n $contains(str, substring) - Tests if string contains substring\n $toMillis(timestamp [, picture]) - Converts ISO 8601 timestamp to milliseconds. E.g. $toMillis(\"2017-11-07T15:07:54.972Z\") => 1510067274972\n $toDate(str | number) - Converts any timestamp string to valid ISO 8601 date string. E.g. $toDate(\"Oct 15, 2024 12:00:00 AM UTC\") => \"2024-10-15T00:00:00.000Z\", $toDate(1728873600000) => \"2024-10-15T00:00:00.000Z\"\n $dateMax(arr) - Returns the maximum date of an array of dates. E.g. $dateMax([\"2017-11-07T15:07:54.972Z\", \"Oct 15, 2012 12:00:00 AM UTC\"]) returns \"2017-11-07T15:07:54.972Z\".\n $dateMin(arr) - Returns the minimum date of an array of dates. E.g. $dateMin($.variants.created_at) returns the minimum created_at date of all variants.\n $dateDiff(date1, date2, unit: \"seconds\" | \"minutes\" | \"hours\" | \"days\") - Returns the difference between two dates in the specified unit. E.g. $dateDiff($.order.created_at, $.order.updated_at, \"days\") returns the number of days between the order created_at and updated_at.\n $now([picture [, timezone]]) - Returns current date and time in ISO 8601 format. E.g. $now() => \"2017-05-15T15:12:59.152Z\"\n $split(str[, separator][, limit]) - Splits string into array\n $join(array[, separator]) - Joins array elements into string\n $match(str, pattern[, limit]) - Returns array of regex matches\n $replace(str, pattern, replacement) - Replaces all occurrences of pattern. E.g. $replace(\"abracadabra\", /a.*?a/, \"*\") returns \"ab*ad*bra\". $replace(\"John Smith\", \"John\", \"Marc\") returns Marc Smith.\n $number(arg) - Converts an argument to a number.\n $min(arr) - Returns minimum number of a number array. E.g. $min($map($.variants.price, $number)) returns the minimum price of all variants.\n $max(arr) - Returns maximum number of a number array. E.g. $max($map($.variants.price, $number)) returns the maximum price of all variants.\n $count(array) - Returns array length\n $sort(array[, function]) - Sorts array\n $distinct(array) - Removes duplicates\n $map(array, function) - Applies function to each element\n $filter(array, function) - Filters array based on predicate\n\n- Error handling:\n - If you get an error like \"is not of a type(s) string/number/object\", try to convert the source field, but also consider that the original field or one of its parent might be null. In this case, add a default value.\n - If the error is something like \"instance is not of a type(s) object\", make sure you REALLY create the target schema with the correct type.\n - If the error is something like \"instance is not of a type(s) array or array/null\". In this case, wrap the source selector in an array to ensure it always returns an array. E.g. \"result\": [$.items]\n - if an object is optional but its fields required, you can add a test and default to {}, but do not set the inner fields to default null.\n\nRemember: The goal is to create valid JSONata expressions that accurately transform the source data structure into the required target structure.";
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import jsonata from "jsonata";
|
|
2
|
-
import type { Schema } from "jsonschema";
|
|
3
|
-
export interface TransformResult {
|
|
4
|
-
success: boolean;
|
|
5
|
-
data?: unknown;
|
|
6
|
-
error?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function applyJsonataWithValidation(data: unknown, expr: string, schema: unknown): Promise<TransformResult>;
|
|
9
|
-
export declare function applyJsonata(data: unknown, expr: string): Promise<unknown>;
|
|
10
|
-
export declare function extendJsonata(expr: string): jsonata.Expression;
|
|
11
|
-
export declare function addNullableToOptional(schema: Schema): Schema;
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import jsonata from "jsonata";
|
|
3
|
-
import { Validator } from "jsonschema";
|
|
4
|
-
export async function applyJsonataWithValidation(data, expr, schema) {
|
|
5
|
-
try {
|
|
6
|
-
const result = await applyJsonata(data, expr);
|
|
7
|
-
if (result === null ||
|
|
8
|
-
result === undefined ||
|
|
9
|
-
(Array.isArray(result) && result.length === 0) ||
|
|
10
|
-
(typeof result === "object" && Object.keys(result).length === 0)) {
|
|
11
|
-
return { success: false, error: "Result is empty" };
|
|
12
|
-
}
|
|
13
|
-
const validator = new Validator();
|
|
14
|
-
const optionalSchema = addNullableToOptional(schema);
|
|
15
|
-
const validation = validator.validate(result, optionalSchema);
|
|
16
|
-
if (!validation.valid) {
|
|
17
|
-
return {
|
|
18
|
-
success: false,
|
|
19
|
-
error: validation.errors
|
|
20
|
-
.map((e) => `${e.stack}. Source: ${e.instance ? JSON.stringify(e.instance) : "undefined"}`)
|
|
21
|
-
.join("\n")
|
|
22
|
-
.slice(0, 5000),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
return { success: true, data: result };
|
|
26
|
-
}
|
|
27
|
-
catch (error) {
|
|
28
|
-
return { success: false, error: `Validation failed: ${error.message}` };
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
export async function applyJsonata(data, expr) {
|
|
32
|
-
try {
|
|
33
|
-
const expression = extendJsonata(expr);
|
|
34
|
-
const result = await expression.evaluate(data);
|
|
35
|
-
return result;
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
throw new Error(`JSONata evaluation failed for expression "${expr}": ${error.message}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
export function extendJsonata(expr) {
|
|
42
|
-
const expression = jsonata(expr);
|
|
43
|
-
expression.registerFunction("max", (arr) => {
|
|
44
|
-
if (Array.isArray(arr)) {
|
|
45
|
-
return Math.max(...arr.map(Number).filter((n) => !Number.isNaN(n)));
|
|
46
|
-
}
|
|
47
|
-
return arr;
|
|
48
|
-
});
|
|
49
|
-
expression.registerFunction("min", (arr) => {
|
|
50
|
-
if (Array.isArray(arr)) {
|
|
51
|
-
return Math.min(...arr.map(Number).filter((n) => !Number.isNaN(n)));
|
|
52
|
-
}
|
|
53
|
-
return arr;
|
|
54
|
-
});
|
|
55
|
-
expression.registerFunction("number", (value) => Number.parseFloat(value));
|
|
56
|
-
expression.registerFunction("substring", (str, start, end) => String(str).substring(start, end));
|
|
57
|
-
expression.registerFunction("replace", (obj, pattern, replacement) => {
|
|
58
|
-
if (Array.isArray(obj)) {
|
|
59
|
-
return obj.map((item) => String(item).replace(pattern, replacement));
|
|
60
|
-
}
|
|
61
|
-
if (typeof obj === "object") {
|
|
62
|
-
return Object.fromEntries(Object.entries(obj || {}).map(([key, value]) => [
|
|
63
|
-
key,
|
|
64
|
-
String(value).replace(pattern, replacement),
|
|
65
|
-
]));
|
|
66
|
-
}
|
|
67
|
-
return String(obj).replace(pattern, replacement);
|
|
68
|
-
});
|
|
69
|
-
expression.registerFunction("toDate", (date) => {
|
|
70
|
-
try {
|
|
71
|
-
// Handle numeric timestamps (milliseconds or seconds)
|
|
72
|
-
if (typeof date === "number" || /^\d+$/.test(date)) {
|
|
73
|
-
const timestamp = typeof date === "number" ? date : Number.parseInt(date, 10);
|
|
74
|
-
// If timestamp is in seconds (typically 10 digits), convert to milliseconds
|
|
75
|
-
const millisTimestamp = timestamp < 10000000000 ? timestamp * 1000 : timestamp;
|
|
76
|
-
return new Date(millisTimestamp).toISOString();
|
|
77
|
-
}
|
|
78
|
-
// Handle date strings in MM/DD/YYYY format
|
|
79
|
-
const match = String(date).match(/^(\d{2})\/(\d{2})\/(\d{4})(?:\s+(\d{2}):(\d{2}):(\d{2}))?$/);
|
|
80
|
-
if (match) {
|
|
81
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
82
|
-
const [_, month, day, year, hours = "00", minutes = "00", seconds = "00"] = match;
|
|
83
|
-
const isoDate = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.000Z`;
|
|
84
|
-
return new Date(isoDate).toISOString();
|
|
85
|
-
}
|
|
86
|
-
// Default case: try standard Date parsing
|
|
87
|
-
return new Date(date).toISOString();
|
|
88
|
-
}
|
|
89
|
-
catch (e) {
|
|
90
|
-
throw new Error(`Invalid date: ${e.message}`);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
expression.registerFunction("dateMax", (dates) => dates.reduce((max, curr) => (new Date(max) > new Date(curr) ? max : curr)));
|
|
94
|
-
expression.registerFunction("dateMin", (dates) => dates.reduce((min, curr) => (new Date(min) < new Date(curr) ? min : curr)));
|
|
95
|
-
expression.registerFunction("dateDiff", (date1, date2, unit = "days") => {
|
|
96
|
-
const d1 = new Date(date1);
|
|
97
|
-
const d2 = new Date(date2);
|
|
98
|
-
const diff = Math.abs(d1.getTime() - d2.getTime());
|
|
99
|
-
switch (unit.toLowerCase()) {
|
|
100
|
-
case "seconds":
|
|
101
|
-
return Math.floor(diff / 1000);
|
|
102
|
-
case "minutes":
|
|
103
|
-
return Math.floor(diff / (1000 * 60));
|
|
104
|
-
case "hours":
|
|
105
|
-
return Math.floor(diff / (1000 * 60 * 60));
|
|
106
|
-
case "days":
|
|
107
|
-
return Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
108
|
-
default:
|
|
109
|
-
return diff; // milliseconds
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
return expression;
|
|
113
|
-
}
|
|
114
|
-
export function addNullableToOptional(schema) {
|
|
115
|
-
if (!schema || typeof schema !== "object")
|
|
116
|
-
return schema;
|
|
117
|
-
const newSchema = { ...schema };
|
|
118
|
-
if (schema.type === "object" && schema.properties) {
|
|
119
|
-
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
120
|
-
newSchema.properties = Object.entries(schema.properties).reduce((acc, [key, value]) => ({
|
|
121
|
-
// biome-ignore lint/performance/noAccumulatingSpread: false positive
|
|
122
|
-
...acc,
|
|
123
|
-
[key]: !required.has(key) ? makeNullable(value) : addNullableToOptional(value),
|
|
124
|
-
}), {});
|
|
125
|
-
}
|
|
126
|
-
if (schema.type === "array" && schema.items) {
|
|
127
|
-
newSchema.items = addNullableToOptional(schema.items);
|
|
128
|
-
}
|
|
129
|
-
return newSchema;
|
|
130
|
-
}
|
|
131
|
-
function makeNullable(schema) {
|
|
132
|
-
if (!schema || typeof schema !== "object")
|
|
133
|
-
return schema;
|
|
134
|
-
const newSchema = { ...schema };
|
|
135
|
-
if (Array.isArray(schema.type)) {
|
|
136
|
-
if (!schema.type.includes("null")) {
|
|
137
|
-
newSchema.type = [...schema.type, "null"];
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
else if (schema.type) {
|
|
141
|
-
newSchema.type = [schema.type, "null"];
|
|
142
|
-
}
|
|
143
|
-
// Recursively process nested properties
|
|
144
|
-
if (schema.properties) {
|
|
145
|
-
newSchema.properties = Object.entries(schema.properties).reduce((acc, [key, value]) => ({
|
|
146
|
-
// biome-ignore lint/performance/noAccumulatingSpread: false positive
|
|
147
|
-
...acc,
|
|
148
|
-
[key]: makeNullable(value),
|
|
149
|
-
}), {});
|
|
150
|
-
}
|
|
151
|
-
if (schema.items) {
|
|
152
|
-
newSchema.items = makeNullable(schema.items);
|
|
153
|
-
}
|
|
154
|
-
return newSchema;
|
|
155
|
-
}
|
package/lib/esm/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/esm/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { type AgentInvokeOptions, type AgentOptions, AIAgent, type AIAgentOptions, type Message, type PromptBuilder } from "@aigne/core";
|
|
2
|
-
import { type NestAgentSchema } from "@aigne/core/loader/agent-yaml.js";
|
|
3
|
-
import type { AgentLoadOptions } from "@aigne/core/loader/index.js";
|
|
4
|
-
import { type Instructions } from "@aigne/core/loader/schema.js";
|
|
5
|
-
import { type ZodType } from "zod";
|
|
6
|
-
import { type StateManagementOptions } from "./type.js";
|
|
7
|
-
/**
|
|
8
|
-
* Configuration options for the Orchestrator Agent
|
|
9
|
-
*/
|
|
10
|
-
export interface OrchestratorAgentOptions<I extends Message = Message, O extends Message = Message> extends Omit<AIAgentOptions<I, O>, "instructions"> {
|
|
11
|
-
objective?: PromptBuilder;
|
|
12
|
-
planner?: OrchestratorAgent<I, O>["planner"];
|
|
13
|
-
worker?: OrchestratorAgent<I, O>["worker"];
|
|
14
|
-
completer?: OrchestratorAgent<I, O>["completer"];
|
|
15
|
-
/**
|
|
16
|
-
* Configuration for managing execution state
|
|
17
|
-
* Prevents context overflow during long-running executions
|
|
18
|
-
*/
|
|
19
|
-
stateManagement?: StateManagementOptions;
|
|
20
|
-
concurrency?: number;
|
|
21
|
-
}
|
|
22
|
-
export interface LoadOrchestratorAgentOptions {
|
|
23
|
-
objective?: string | Instructions;
|
|
24
|
-
planner?: NestAgentSchema;
|
|
25
|
-
worker?: NestAgentSchema;
|
|
26
|
-
completer?: NestAgentSchema;
|
|
27
|
-
stateManagement?: StateManagementOptions;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Orchestrator Agent Class
|
|
31
|
-
*
|
|
32
|
-
* This Agent is responsible for:
|
|
33
|
-
* 1. Generating an execution plan based on the objective
|
|
34
|
-
* 2. Breaking down the plan into steps and tasks
|
|
35
|
-
* 3. Coordinating the execution of steps and tasks
|
|
36
|
-
* 4. Synthesizing the final result
|
|
37
|
-
*
|
|
38
|
-
* Workflow:
|
|
39
|
-
* - Receives input objective
|
|
40
|
-
* - Uses planner to create execution plan
|
|
41
|
-
* - Executes tasks and steps according to the plan
|
|
42
|
-
* - Synthesizes final result through completer
|
|
43
|
-
*/
|
|
44
|
-
export declare class OrchestratorAgent<I extends Message = Message, O extends Message = Message> extends AIAgent<I, O> {
|
|
45
|
-
tag: string;
|
|
46
|
-
static schema<T>({ filepath }: {
|
|
47
|
-
filepath: string;
|
|
48
|
-
}): ZodType<T>;
|
|
49
|
-
static load<I extends Message = Message, O extends Message = Message>({ filepath, parsed, options, }: {
|
|
50
|
-
filepath: string;
|
|
51
|
-
parsed: LoadOrchestratorAgentOptions & AgentOptions<I, O>;
|
|
52
|
-
options?: AgentLoadOptions;
|
|
53
|
-
}): Promise<OrchestratorAgent<I, O>>;
|
|
54
|
-
/**
|
|
55
|
-
* Factory method to create an OrchestratorAgent instance
|
|
56
|
-
* @param options - Configuration options for the Orchestrator Agent
|
|
57
|
-
* @returns A new OrchestratorAgent instance
|
|
58
|
-
*/
|
|
59
|
-
static from<I extends Message, O extends Message>(options: OrchestratorAgentOptions<I, O>): OrchestratorAgent<I, O>;
|
|
60
|
-
/**
|
|
61
|
-
* Creates an OrchestratorAgent instance
|
|
62
|
-
* @param options - Configuration options for the Orchestrator Agent
|
|
63
|
-
*/
|
|
64
|
-
constructor(options: OrchestratorAgentOptions<I, O>);
|
|
65
|
-
private objective?;
|
|
66
|
-
private planner;
|
|
67
|
-
private worker;
|
|
68
|
-
private completer;
|
|
69
|
-
private stateManagement?;
|
|
70
|
-
private concurrency;
|
|
71
|
-
/**
|
|
72
|
-
* Compress execution state to prevent context overflow
|
|
73
|
-
* Uses reverse accumulation to efficiently find optimal task count
|
|
74
|
-
*/
|
|
75
|
-
private compressState;
|
|
76
|
-
process(input: I, options: AgentInvokeOptions): AsyncGenerator<import("@aigne/core").AgentResponseChunk<O>, void, unknown>;
|
|
77
|
-
}
|
|
78
|
-
export default OrchestratorAgent;
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
import { AIAgent, } from "@aigne/core";
|
|
2
|
-
import { getNestAgentSchema } from "@aigne/core/loader/agent-yaml.js";
|
|
3
|
-
import { camelizeSchema, getInstructionsSchema, instructionsToPromptBuilder, optionalize, } from "@aigne/core/loader/schema.js";
|
|
4
|
-
import { isAgent } from "@aigne/core/utils/agent-utils.js";
|
|
5
|
-
import * as fastq from "@aigne/core/utils/queue.js";
|
|
6
|
-
import { estimateTokens } from "@aigne/core/utils/token-estimator.js";
|
|
7
|
-
import { omit, pick } from "@aigne/core/utils/type-utils.js";
|
|
8
|
-
import { z } from "zod";
|
|
9
|
-
import { ORCHESTRATOR_COMPLETE_PROMPT, TODO_PLANNER_PROMPT_TEMPLATE, TODO_WORKER_PROMPT_TEMPLATE, } from "./prompt.js";
|
|
10
|
-
import { completerInputSchema, DEFAULT_MAX_ITERATIONS, plannerInputSchema, plannerOutputSchema, stateManagementOptionsSchema, workerInputSchema, workerOutputSchema, } from "./type.js";
|
|
11
|
-
const defaultPlannerOptions = {
|
|
12
|
-
name: "Planner",
|
|
13
|
-
instructions: TODO_PLANNER_PROMPT_TEMPLATE,
|
|
14
|
-
inputSchema: plannerInputSchema,
|
|
15
|
-
outputSchema: plannerOutputSchema,
|
|
16
|
-
};
|
|
17
|
-
const defaultWorkerOptions = {
|
|
18
|
-
name: "Worker",
|
|
19
|
-
taskTitle: "Execute Task: {{task}}",
|
|
20
|
-
instructions: TODO_WORKER_PROMPT_TEMPLATE,
|
|
21
|
-
inputSchema: workerInputSchema,
|
|
22
|
-
outputSchema: workerOutputSchema,
|
|
23
|
-
};
|
|
24
|
-
const defaultCompleterOptions = {
|
|
25
|
-
name: "Completer",
|
|
26
|
-
instructions: ORCHESTRATOR_COMPLETE_PROMPT,
|
|
27
|
-
inputSchema: completerInputSchema,
|
|
28
|
-
};
|
|
29
|
-
const DEFAULT_CONCURRENCY = 5;
|
|
30
|
-
/**
|
|
31
|
-
* Orchestrator Agent Class
|
|
32
|
-
*
|
|
33
|
-
* This Agent is responsible for:
|
|
34
|
-
* 1. Generating an execution plan based on the objective
|
|
35
|
-
* 2. Breaking down the plan into steps and tasks
|
|
36
|
-
* 3. Coordinating the execution of steps and tasks
|
|
37
|
-
* 4. Synthesizing the final result
|
|
38
|
-
*
|
|
39
|
-
* Workflow:
|
|
40
|
-
* - Receives input objective
|
|
41
|
-
* - Uses planner to create execution plan
|
|
42
|
-
* - Executes tasks and steps according to the plan
|
|
43
|
-
* - Synthesizes final result through completer
|
|
44
|
-
*/
|
|
45
|
-
export class OrchestratorAgent extends AIAgent {
|
|
46
|
-
tag = "OrchestratorAgent";
|
|
47
|
-
static schema({ filepath }) {
|
|
48
|
-
const nestAgentSchema = getNestAgentSchema({ filepath });
|
|
49
|
-
const instructionsSchema = getInstructionsSchema({ filepath });
|
|
50
|
-
return camelizeSchema(z.object({
|
|
51
|
-
objective: optionalize(instructionsSchema),
|
|
52
|
-
planner: optionalize(nestAgentSchema),
|
|
53
|
-
worker: optionalize(nestAgentSchema),
|
|
54
|
-
completer: optionalize(nestAgentSchema),
|
|
55
|
-
stateManagement: optionalize(camelizeSchema(stateManagementOptionsSchema)),
|
|
56
|
-
concurrency: optionalize(z.number().int().min(1).default(DEFAULT_CONCURRENCY)),
|
|
57
|
-
}));
|
|
58
|
-
}
|
|
59
|
-
static async load({ filepath, parsed, options, }) {
|
|
60
|
-
const valid = await OrchestratorAgent.schema({
|
|
61
|
-
filepath,
|
|
62
|
-
}).parseAsync(parsed);
|
|
63
|
-
return new OrchestratorAgent({
|
|
64
|
-
...parsed,
|
|
65
|
-
objective: valid.objective ? instructionsToPromptBuilder(valid.objective) : undefined,
|
|
66
|
-
planner: valid.planner
|
|
67
|
-
? (await options?.loadNestAgent(filepath, valid.planner, options, {
|
|
68
|
-
...defaultPlannerOptions,
|
|
69
|
-
afs: parsed.afs,
|
|
70
|
-
skills: parsed.skills,
|
|
71
|
-
}))
|
|
72
|
-
: undefined,
|
|
73
|
-
worker: valid.worker
|
|
74
|
-
? (await options?.loadNestAgent(filepath, valid.worker, options, {
|
|
75
|
-
...defaultWorkerOptions,
|
|
76
|
-
afs: parsed.afs,
|
|
77
|
-
skills: parsed.skills,
|
|
78
|
-
}))
|
|
79
|
-
: undefined,
|
|
80
|
-
completer: valid.completer
|
|
81
|
-
? (await options?.loadNestAgent(filepath, valid.completer, options, {
|
|
82
|
-
...defaultCompleterOptions,
|
|
83
|
-
outputSchema: parsed.outputSchema,
|
|
84
|
-
afs: parsed.afs,
|
|
85
|
-
skills: parsed.skills,
|
|
86
|
-
}))
|
|
87
|
-
: undefined,
|
|
88
|
-
stateManagement: valid.stateManagement,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Factory method to create an OrchestratorAgent instance
|
|
93
|
-
* @param options - Configuration options for the Orchestrator Agent
|
|
94
|
-
* @returns A new OrchestratorAgent instance
|
|
95
|
-
*/
|
|
96
|
-
static from(options) {
|
|
97
|
-
return new OrchestratorAgent(options);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Creates an OrchestratorAgent instance
|
|
101
|
-
* @param options - Configuration options for the Orchestrator Agent
|
|
102
|
-
*/
|
|
103
|
-
constructor(options) {
|
|
104
|
-
super({ ...options });
|
|
105
|
-
this.objective = options.objective;
|
|
106
|
-
this.planner = isAgent(options.planner)
|
|
107
|
-
? options.planner
|
|
108
|
-
: new AIAgent({
|
|
109
|
-
...options,
|
|
110
|
-
...defaultPlannerOptions,
|
|
111
|
-
});
|
|
112
|
-
this.worker = isAgent(options.worker)
|
|
113
|
-
? options.worker
|
|
114
|
-
: new AIAgent({
|
|
115
|
-
...options,
|
|
116
|
-
...defaultWorkerOptions,
|
|
117
|
-
});
|
|
118
|
-
this.completer = isAgent(options.completer)
|
|
119
|
-
? options.completer
|
|
120
|
-
: new AIAgent({
|
|
121
|
-
...omit(options, "inputSchema"),
|
|
122
|
-
...defaultCompleterOptions,
|
|
123
|
-
outputKey: options.outputKey,
|
|
124
|
-
outputSchema: options.outputSchema,
|
|
125
|
-
});
|
|
126
|
-
// Initialize state management config
|
|
127
|
-
this.stateManagement = options.stateManagement;
|
|
128
|
-
this.concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
129
|
-
}
|
|
130
|
-
objective;
|
|
131
|
-
planner;
|
|
132
|
-
worker;
|
|
133
|
-
completer;
|
|
134
|
-
stateManagement;
|
|
135
|
-
concurrency;
|
|
136
|
-
/**
|
|
137
|
-
* Compress execution state to prevent context overflow
|
|
138
|
-
* Uses reverse accumulation to efficiently find optimal task count
|
|
139
|
-
*/
|
|
140
|
-
compressState(state) {
|
|
141
|
-
const { maxTokens, keepRecent } = this.stateManagement ?? {};
|
|
142
|
-
if (!maxTokens && !keepRecent) {
|
|
143
|
-
return state;
|
|
144
|
-
}
|
|
145
|
-
const tasks = state.tasks;
|
|
146
|
-
let selectedTasks = tasks;
|
|
147
|
-
// Step 1: Apply keepRecent limit if configured
|
|
148
|
-
if (keepRecent && tasks.length > keepRecent) {
|
|
149
|
-
selectedTasks = tasks.slice(-keepRecent);
|
|
150
|
-
}
|
|
151
|
-
// Step 2: Apply maxTokens limit if configured
|
|
152
|
-
if (maxTokens && selectedTasks.length > 0) {
|
|
153
|
-
// Start from the most recent task and accumulate backwards
|
|
154
|
-
let accumulatedTokens = 0;
|
|
155
|
-
let taskCount = 0;
|
|
156
|
-
for (let i = selectedTasks.length - 1; i >= 0; i--) {
|
|
157
|
-
const taskJson = JSON.stringify(selectedTasks[i]);
|
|
158
|
-
const taskTokens = estimateTokens(taskJson);
|
|
159
|
-
if (accumulatedTokens + taskTokens > maxTokens && taskCount > 0) {
|
|
160
|
-
// Stop if adding this task would exceed limit
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
accumulatedTokens += taskTokens;
|
|
164
|
-
taskCount++;
|
|
165
|
-
}
|
|
166
|
-
// Keep the most recent N tasks that fit within token limit
|
|
167
|
-
if (taskCount < selectedTasks.length) {
|
|
168
|
-
selectedTasks = selectedTasks.slice(-taskCount);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return { tasks: selectedTasks };
|
|
172
|
-
}
|
|
173
|
-
async *process(input, options) {
|
|
174
|
-
const model = this.model || options.model || options.context.model;
|
|
175
|
-
if (!model)
|
|
176
|
-
throw new Error("model is required to run OrchestratorAgent");
|
|
177
|
-
const objective = (await this.objective?.buildPrompt({
|
|
178
|
-
input,
|
|
179
|
-
context: options.context,
|
|
180
|
-
}))?.prompt;
|
|
181
|
-
const executionState = { tasks: [] };
|
|
182
|
-
let iterationCount = 0;
|
|
183
|
-
const maxIterations = this.stateManagement?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
184
|
-
while (true) {
|
|
185
|
-
// Check if maximum iterations reached
|
|
186
|
-
if (maxIterations && iterationCount >= maxIterations) {
|
|
187
|
-
console.warn(`Maximum iterations (${maxIterations}) reached. Stopping execution.`);
|
|
188
|
-
executionState.tasks.push({
|
|
189
|
-
status: "failed",
|
|
190
|
-
error: { message: `ERROR: Maximum iterations (${maxIterations}) reached` },
|
|
191
|
-
task: `ERROR: Objective not completed within iteration limit of ${maxIterations}`,
|
|
192
|
-
createdAt: Date.now(),
|
|
193
|
-
completedAt: Date.now(),
|
|
194
|
-
});
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
iterationCount++;
|
|
198
|
-
// Compress state for planner input if needed
|
|
199
|
-
const compressedState = this.compressState(executionState);
|
|
200
|
-
const plan = await this.invokeChildAgent(this.planner, {
|
|
201
|
-
objective,
|
|
202
|
-
executionState: compressedState,
|
|
203
|
-
...pick(input, this.planner.inputKeys),
|
|
204
|
-
}, { ...options, model, streaming: false });
|
|
205
|
-
if (plan.finished || !plan.nextTasks?.length) {
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
const createdAt = Date.now();
|
|
209
|
-
const queue = fastq.promise(async ({ task }) => {
|
|
210
|
-
const taskResult = await this.invokeChildAgent(this.worker, {
|
|
211
|
-
objective,
|
|
212
|
-
executionState: compressedState,
|
|
213
|
-
task,
|
|
214
|
-
...pick(input, this.worker.inputKeys),
|
|
215
|
-
}, { ...options, model, streaming: false })
|
|
216
|
-
.then((res) => {
|
|
217
|
-
if (res.error || res.success === false) {
|
|
218
|
-
return { status: "failed", result: res.result, error: res.error };
|
|
219
|
-
}
|
|
220
|
-
return { status: "completed", result: res.result };
|
|
221
|
-
})
|
|
222
|
-
.catch((error) => ({
|
|
223
|
-
status: "failed",
|
|
224
|
-
error: { message: error instanceof Error ? error.message : String(error) },
|
|
225
|
-
}));
|
|
226
|
-
return { ...taskResult, task, createdAt, completedAt: Date.now() };
|
|
227
|
-
}, plan.parallelTasks ? this.concurrency : 1);
|
|
228
|
-
const taskResults = await Promise.all(plan.nextTasks.map((task) => queue.push({ task })));
|
|
229
|
-
executionState.tasks.push(...taskResults);
|
|
230
|
-
}
|
|
231
|
-
// Compress state for completer input if needed
|
|
232
|
-
const compressedState = this.compressState(executionState);
|
|
233
|
-
yield* await this.invokeChildAgent(this.completer, {
|
|
234
|
-
objective,
|
|
235
|
-
executionState: compressedState,
|
|
236
|
-
...pick(input, this.completer.inputKeys),
|
|
237
|
-
}, { ...options, model, streaming: true });
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
export default OrchestratorAgent;
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare const ORCHESTRATOR_COMPLETE_PROMPT = "You are an intelligent assistant that synthesizes and presents the results of completed tasks.\n\n{% if $afs.enabled %}\n## Environment\n\n### AFS\n{{ $afs.description }}\n\n```yaml alt=\"The modules available in the AFS\"\n{{ $afs.modules | yaml.stringify }}\n```\n{% endif %}\n\n## User's Objective\n\n```txt alt=\"The user's latest objective you need to address\"\n{{ objective }}\n```\n\n## Current Execution State\n\n```yaml alt=\"The latest execution state\"\n{{ executionState | yaml.stringify }}\n```\n\n## Your Task\nBased on the execution results above, provide a comprehensive and helpful response to the user's objective.\n";
|
|
2
|
-
export declare const TODO_PLANNER_PROMPT_TEMPLATE = "Your responsibility is to decide the next tasks based on the current execution state.\n\n## Responsibilities\n\nYou are the Planner in the Orchestrator. The entire Orchestrator completes tasks through collaboration of three roles:\n\n1. **Planner (you)** analyzes the current state and outputs \"nextTasks\" (one or more tasks)\n2. **Worker** executes the tasks and updates the execution state\n3. **Loop back to step 1**, Planner plans the next tasks based on the new state\n4. **Repeat steps 1-3** until Planner determines the objective is complete\n5. **Planner** sets \"finished: true\"\n6. **Completer** generates the final report and returns it to the user\n\n{% if $afs.enabled %}\n## Environment\n\n### AFS\n{{ $afs.description }}\n\n```yaml alt=\"The modules available in the AFS\"\n{{ $afs.modules | yaml.stringify }}\n```\n{% endif %}\n\n## User's Objective\n\n```txt alt=\"The user's next objective you need to plan for\"\n{{ objective }}\n```\n\n## Current Execution State\n\n```yaml alt=\"The latest execution state\"\n{{ executionState | yaml.stringify }}\n```\n\n## How to Plan Tasks\n\n### 1. Determine if Tasks Are Needed\n\nFirst, assess whether the objective requires any tasks at all. Ask yourself:\n\n**Does this objective require tasks?**\n\nConsider if completing the objective needs:\n- **Information gathering**: Does it need to collect or retrieve information?\n- **Analysis or processing**: Does it need to analyze, process, or compute something?\n- **State dependency**: Does it depend on information not yet in the execution state?\n\n**Set \"finished: true\" immediately when:**\n- The objective requires no exploration, analysis, or information gathering\n- The current execution state already contains everything needed to respond\n- The objective is purely conversational without requiring any action\n\n**Plan tasks when:**\n- The objective requires gathering information from external sources\n- The objective requires analysis, processing, or computation to be performed\n- Additional information must be collected before a complete response can be given\n\n### 2. Analyze Information Requirements\n\nIf tasks are needed, think about the current state and objective:\n- What information is needed to complete the objective?\n- Where can this information be obtained from?\n- What information has already been collected? What is still missing?\n- Is deeper exploration needed, or is it ready to generate a summary?\n\n### 3. Decision Principles\n\n- **Plan one or more tasks per iteration**: You can output multiple tasks when they are independent\n- **Only decide, don't execute**: You only output task descriptions, actual execution is done by the Worker\n- **Trust the iterative process**: You will be called again after tasks complete, allowing you to adjust the plan dynamically\n- **Avoid duplicate work**: Review the execution history to understand what has been completed\n- **Goal-oriented descriptions**: Task descriptions should state \"what to do\", not \"how to do it\"\n- **Handle failures appropriately**: If a previous task failed, decide whether to retry, skip, or use an alternative approach\n\n### 4. Parallel vs Sequential Execution\n\nYou can specify whether tasks should run in parallel or sequentially using `parallelTasks`.\n\n**IMPORTANT: When tasks run in parallel, they CANNOT see each other's results.** Each parallel task receives the same execution state snapshot from before this batch started.\n\n**Set `parallelTasks: true` ONLY when ALL conditions are met:**\n- Tasks operate on **completely independent** data sources or resources\n- Task results are **not needed by other tasks** in the same batch\n- Tasks have **no ordering requirements** between them\n- You are **100% certain** there are no dependencies\n\n**Set `parallelTasks: false` (default) when ANY of these apply:**\n- Any task needs results from another task in the same batch\n- Tasks must be executed in a specific order\n- Tasks operate on shared resources that could conflict\n- You are **uncertain** whether tasks are truly independent\n\n**When in doubt, use sequential execution.** It's safer to be slower than to produce incorrect results.\n\n### 5. Decision Making at Different Stages\n\nFlexibly decide the next step based on current progress:\n\n**Exploration Stage**:\n- Plan exploration tasks to gather required information\n- If exploring multiple independent sources, consider parallel execution\n\n**Processing Stage**:\n- Process gathered information\n- Use sequential execution when processing depends on previous results\n\n**Summary Stage**:\n- When sufficient information is collected, plan to generate a summary or report task\n\n**Completion Stage**:\n- Set \"finished: true\" when:\n - The objective doesn't require any tasks\n - All necessary tasks are completed\n - The objective is fully achieved\n- This will trigger the Completer to integrate all information and generate the final report\n\n## Understanding Task Status\n\nEach task in the execution state has a status:\n- **completed**: Task finished successfully, result is available\n- **failed**: Task encountered an error, check error field for details\n- **pending**: Task has not been executed yet\n\n## Output Format\n\n```yaml\nnextTasks: # List of tasks to execute (omit if finished)\n - \"task description 1\"\n - \"task description 2\"\nparallelTasks: false # true if tasks can run in parallel, false for sequential (default: false)\nfinished: false # true if objective is achieved and no more tasks needed\n```\n\n**Notes:**\n- Task descriptions should be **goal-oriented**, not specifying concrete operations\n- Let the worker autonomously decide how to complete each task\n- Default to sequential execution (`parallelTasks: false`) unless you're certain tasks are independent\n- When `finished: true`, omit `nextTasks`\n";
|
|
3
|
-
export declare const TODO_WORKER_PROMPT_TEMPLATE = "You are a task execution agent. Your job is to execute the specific task assigned to you - nothing more, nothing less.\n\n{% if $afs.enabled %}\n## Environment\n\n### AFS\n{{ $afs.description }}\n\n```yaml alt=\"The modules available in the AFS\"\n{{ $afs.modules | yaml.stringify }}\n```\n{% endif %}\n\n## User's Objective\n\n```txt alt=\"The user's objective provide for context only\"\n{{ objective }}\n```\n\n**CRITICAL CONSTRAINT**: The objective above is provided ONLY for context. You must NOT attempt to:\n- Solve the entire objective\n- Plan additional steps beyond your current task\n- Make decisions about what should happen next\n- Execute any tasks other than the one explicitly assigned to you below\n\n## Latest Execution State\n\n```yaml alt=\"The latest execution state for your reference\"\n{{ executionState | yaml.stringify }}\n```\n\n## Your Current Task\n\n```txt alt=\"The specific task you need to execute now\"\n{{ task }}\n```\n\n## Important Instructions\n- Focus EXCLUSIVELY on completing the current task described above\n- The task is self-contained - execute it completely and accurately\n- Do NOT perform additional tasks beyond what is specified\n- Do NOT try to determine what should happen after this task\n- Use the available tools and skills to accomplish this specific task\n- Return a clear result that the planner can use to decide the next step\n\n## Output Format\nReturn your task execution result as a structured response. The output schema will guide you on the required fields.\n";
|