Skip to content

Commit df76070

Browse files
committed
completion-error-handler
1 parent 1cfbdf4 commit df76070

8 files changed

Lines changed: 124 additions & 18 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "agent-swarm-kit",
3-
"version": "1.1.143",
3+
"version": "1.1.144",
44
"description": "A TypeScript library for building orchestrated framework-agnostic multi-agent AI systems",
55
"author": {
66
"name": "Petr Tripolsky",

src/config/emitters.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ import { Subject } from "functools-kit";
22
import { SessionId } from "../interfaces/Session.interface";
33

44
export const disposeSubject = new Subject<SessionId>();
5+
6+
export const errorSubject = new Subject<[SessionId, Error]>();

src/functions/setup/addCompletion.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@ import { ICompletionSchema } from "../../interfaces/Completion.interface";
22
import swarm from "../../lib";
33
import { GLOBAL_CONFIG } from "../../config/params";
44
import beginContext from "../../utils/beginContext";
5+
import mapCompletionSchema from "../../helpers/mapCompletionSchema";
56

67
const METHOD_NAME = "function.setup.addCompletion";
78

89
/**
910
* Function implementation
1011
*/
1112
const addCompletionInternal = beginContext(
12-
(completionSchema: ICompletionSchema) => {
13+
(completionPublicSchema: ICompletionSchema) => {
1314
// Log the operation details if logging is enabled in GLOBAL_CONFIG
1415
GLOBAL_CONFIG.CC_LOGGER_ENABLE_LOG &&
1516
swarm.loggerService.log(METHOD_NAME, {
16-
completionSchema,
17+
completionSchema: completionPublicSchema,
1718
});
1819

20+
const completionSchema = mapCompletionSchema(completionPublicSchema);
21+
1922
// Register the completion in the validation and schema services
2023
swarm.completionValidationService.addCompletion(
2124
completionSchema.completionName

src/functions/target/execute.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { AgentName } from "../../interfaces/Agent.interface";
33
import { GLOBAL_CONFIG } from "../../config/params";
44
import swarm, { ExecutionContextService } from "../../lib";
55
import beginContext from "../../utils/beginContext";
6+
import { errorSubject } from "../../config/emitters";
67

78
const METHOD_NAME = "function.target.execute";
89

@@ -57,27 +58,45 @@ const executeInternal = beginContext(
5758
agentName,
5859
swarmName,
5960
});
60-
const result = await swarm.sessionPublicService.execute(
61+
62+
let result = "";
63+
let errorValue = null;
64+
65+
const unError = errorSubject.once(([errorClientId, error]) => {
66+
if (clientId === errorClientId) {
67+
errorValue = error;
68+
}
69+
});
70+
71+
result = await swarm.sessionPublicService.execute(
6172
content,
6273
"tool",
6374
METHOD_NAME,
6475
clientId,
6576
swarmName
6677
);
78+
79+
unError();
80+
81+
if (errorValue) {
82+
throw errorValue;
83+
}
84+
6785
isFinished = swarm.perfService.endExecution(
6886
executionId,
6987
clientId,
7088
result.length
7189
);
72-
swarm.busService.commitExecutionEnd(clientId, {
73-
agentName,
74-
swarmName,
75-
});
90+
7691
return result;
7792
} finally {
7893
if (!isFinished) {
7994
swarm.perfService.endExecution(executionId, clientId, 0);
8095
}
96+
swarm.busService.commitExecutionEnd(clientId, {
97+
agentName,
98+
swarmName,
99+
});
81100
swarm.executionValidationService.decrementCount(executionId, clientId, swarmName);
82101
}
83102
},

src/functions/target/json.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
IOutlineResult,
1313
} from "../../interfaces/Outline.interface";
1414
import { getErrorMessage, randomString } from "functools-kit";
15+
import { errorSubject } from "../../config/emitters";
16+
import { IModelMessage } from "../../model/ModelMessage.model";
1517

1618
const METHOD_NAME = "function.target.json";
1719

@@ -79,6 +81,7 @@ const jsonInternal = beginContext(
7981
swarm.outlineValidationService.validate(outlineName, METHOD_NAME);
8082

8183
const resultId = randomString();
84+
const clientId = `${resultId}_outline`;
8285

8386
const {
8487
getOutlineHistory,
@@ -146,12 +149,29 @@ const jsonInternal = beginContext(
146149
await getOutlineHistory(inputArgs);
147150
const messages = await history.list();
148151
try {
149-
const output = await getCompletion({
152+
let output: IModelMessage | IOutlineMessage;
153+
let errorValue = null;
154+
155+
const unError = errorSubject.once(([errorClientId, error]) => {
156+
if (clientId === errorClientId) {
157+
errorValue = error;
158+
}
159+
});
160+
161+
output = await getCompletion({
162+
clientId,
150163
messages: await history.list(),
151164
mode: "tool",
152165
outlineName,
153166
format,
154167
});
168+
169+
unError();
170+
171+
if (errorValue) {
172+
throw errorValue;
173+
}
174+
155175
if (completionCallbacks?.onComplete) {
156176
completionCallbacks.onComplete(
157177
{
@@ -189,11 +209,14 @@ const jsonInternal = beginContext(
189209
return result;
190210
} catch (error) {
191211
errorMessage = getErrorMessage(error);
192-
console.error(`agent-swarm outline error outlineName=${outlineName} attempt=${attempt}`, {
193-
param,
194-
lastData,
195-
errorMessage,
196-
})
212+
console.error(
213+
`agent-swarm outline error outlineName=${outlineName} attempt=${attempt}`,
214+
{
215+
param,
216+
lastData,
217+
errorMessage,
218+
}
219+
);
197220
}
198221
}
199222
const result = {

src/functions/test/overrideCompletion.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ICompletionSchema } from "../../interfaces/Completion.interface";
22
import swarm from "../../lib";
33
import { GLOBAL_CONFIG } from "../../config/params";
44
import beginContext from "../../utils/beginContext";
5-
import removeUndefined from "../../helpers/removeUndefined";
5+
import mapCompletionSchema from "../../helpers/mapCompletionSchema";
66

77
const METHOD_NAME = "function.test.overrideCompletion";
88

@@ -20,7 +20,7 @@ const overrideCompletionInternal = beginContext(
2020
completionSchema: publicCompletionSchema,
2121
});
2222

23-
const completionSchema = removeUndefined(publicCompletionSchema);
23+
const completionSchema = mapCompletionSchema(publicCompletionSchema);
2424

2525
return swarm.completionSchemaService.override(
2626
completionSchema.completionName,

src/helpers/mapCompletionSchema.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { ICompletionSchema } from "../interfaces/Completion.interface";
2+
import removeUndefined from "./removeUndefined";
3+
import { errorSubject } from "../config/emitters";
4+
5+
type TCompletionSchema = {
6+
completionName: ICompletionSchema["completionName"];
7+
} & Partial<ICompletionSchema>;
8+
9+
/**
10+
* Maps a completion schema by wrapping its `getCompletion` method with error handling.
11+
* If an error occurs during the execution of `getCompletion`, it emits the error using `errorSubject`.
12+
* Also removes any undefined properties from the resulting schema object.
13+
*
14+
* @param {ICompletionSchema} param0 - The completion schema object containing a `getCompletion` function and other properties.
15+
* @returns {ICompletionSchema} - The new completion schema with error-handled `getCompletion` and no undefined properties.
16+
*/
17+
export const mapCompletionSchema = ({
18+
getCompletion,
19+
...schema
20+
}: TCompletionSchema): ICompletionSchema =>
21+
removeUndefined({
22+
...schema,
23+
getCompletion: getCompletion
24+
? async ({
25+
mode,
26+
messages,
27+
agentName,
28+
clientId,
29+
format,
30+
outlineName,
31+
tools,
32+
}) => {
33+
const params = {
34+
mode,
35+
messages,
36+
agentName,
37+
clientId,
38+
format,
39+
outlineName,
40+
tools,
41+
};
42+
try {
43+
return await getCompletion(params);
44+
} catch (error) {
45+
if (clientId) {
46+
errorSubject.next([clientId, error]);
47+
}
48+
return {
49+
agentName,
50+
content: "",
51+
mode,
52+
role: "assistant",
53+
};
54+
}
55+
}
56+
: undefined,
57+
});
58+
59+
export default mapCompletionSchema;

0 commit comments

Comments
 (0)