Skip to content

Commit a6384c6

Browse files
committed
outline-completion
1 parent ca4a14b commit a6384c6

11 files changed

Lines changed: 942 additions & 726 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.116",
3+
"version": "1.1.118",
44
"description": "A TypeScript library for building orchestrated framework-agnostic multi-agent AI systems",
55
"author": {
66
"name": "Petr Tripolsky",

src/client/ClientAgent.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,12 @@ const RUN_FN = async (incoming: string, self: ClientAgent): Promise<string> => {
263263
mode: "user" as const,
264264
tools: [],
265265
};
266-
const rawMessage = await self.params.completion.getCompletion(args);
266+
const completionMessage = await self.params.completion.getCompletion(args);
267+
const rawMessage: IModelMessage = {
268+
agentName: self.params.agentName,
269+
mode: "tool",
270+
...completionMessage,
271+
};
267272
self.params.completion.callbacks?.onComplete &&
268273
self.params.completion.callbacks?.onComplete(args, rawMessage);
269274
const message = await self.params.map(
@@ -1039,7 +1044,12 @@ export class ClientAgent implements IAgent {
10391044
tools
10401045
),
10411046
};
1042-
const output = await this.params.completion.getCompletion(args);
1047+
const rawMessage = await this.params.completion.getCompletion(args);
1048+
const output: IModelMessage = {
1049+
agentName: this.params.agentName,
1050+
mode: "tool",
1051+
...rawMessage,
1052+
};
10431053
if (GLOBAL_CONFIG.CC_RESQUE_STRATEGY === "flush") {
10441054
this.params.completion.callbacks?.onComplete &&
10451055
this.params.completion.callbacks?.onComplete(args, output);
@@ -1106,7 +1116,12 @@ export class ClientAgent implements IAgent {
11061116
tools
11071117
),
11081118
};
1109-
const output = await this.params.completion.getCompletion(args);
1119+
const rawMessage = await this.params.completion.getCompletion(args);
1120+
const output: IModelMessage = {
1121+
agentName: this.params.agentName,
1122+
mode: "tool",
1123+
...rawMessage,
1124+
};
11101125
this.params.completion.callbacks?.onComplete &&
11111126
this.params.completion.callbacks?.onComplete(args, output);
11121127
return {

src/functions/target/json.ts

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
IOutlineValidationArgs,
1212
IOutlineResult,
1313
} from "../../interfaces/Outline.interface";
14-
import { getErrorMessage, randomString, str } from "functools-kit";
14+
import { getErrorMessage, randomString } from "functools-kit";
1515

1616
const METHOD_NAME = "function.target.json";
1717

@@ -32,11 +32,23 @@ class OutlineHistory implements IOutlineHistory {
3232
* @param {string} [prompt] - An optional system prompt to initialize the history with.
3333
* @constructor
3434
*/
35-
constructor(prompt?: string) {
36-
prompt && this.messages.push({
37-
role: "system",
38-
content: prompt
39-
})
35+
constructor(prompt?: string | string[]) {
36+
if (!prompt) {
37+
return;
38+
}
39+
if (typeof prompt === "string") {
40+
this.messages.push({
41+
role: "system",
42+
content: prompt,
43+
});
44+
return;
45+
}
46+
prompt.forEach((content) => {
47+
this.messages.push({
48+
role: "system",
49+
content,
50+
});
51+
});
4052
}
4153

4254
/**
@@ -93,20 +105,25 @@ const jsonInternal = beginContext(
93105
const resultId = randomString();
94106

95107
const {
96-
getStructuredOutput,
108+
getOutlineHistory,
109+
completion,
97110
validations = [],
98111
maxAttempts = MAX_ATTEMPTS,
99112
format,
100113
prompt,
101-
callbacks,
114+
callbacks: outlineCallbacks,
102115
} = swarm.outlineSchemaService.get(outlineName);
103116

117+
swarm.completionValidationService.validate(completion, METHOD_NAME);
118+
119+
const { getCompletion, callbacks: completionCallbacks } =
120+
swarm.completionSchemaService.get(completion);
121+
104122
let errorMessage: string = "";
105123
let history: OutlineHistory;
106124

107-
const systemPrompt = str.newline(
108-
typeof prompt === "function" ? await prompt(outlineName) : prompt
109-
);
125+
const systemPrompt =
126+
typeof prompt === "function" ? await prompt(outlineName) : prompt;
110127

111128
for (let attempt = 0; attempt < maxAttempts; attempt++) {
112129
history = new OutlineHistory(systemPrompt);
@@ -116,41 +133,52 @@ const jsonInternal = beginContext(
116133
param,
117134
history,
118135
};
119-
if (callbacks?.onAttempt) {
120-
callbacks.onAttempt(inputArgs);
136+
if (outlineCallbacks?.onAttempt) {
137+
outlineCallbacks.onAttempt(inputArgs);
121138
}
122-
const data = await getStructuredOutput(inputArgs);
123-
const validationArgs: IOutlineValidationArgs = {
124-
...inputArgs,
125-
data,
126-
};
127-
let isValid = true;
128-
for (const validation of validations) {
129-
const validate =
130-
typeof validation === "object" ? validation.validate : validation;
131-
try {
139+
await getOutlineHistory(inputArgs);
140+
const messages = await history.list();
141+
try {
142+
const output = await getCompletion({
143+
messages: await history.list(),
144+
mode: "tool",
145+
outlineName,
146+
});
147+
if (completionCallbacks?.onComplete) {
148+
completionCallbacks.onComplete(
149+
{
150+
messages,
151+
mode: "tool",
152+
outlineName,
153+
},
154+
output
155+
);
156+
}
157+
const data = JSON.parse(output.content) as IOutlineData;
158+
const validationArgs: IOutlineValidationArgs = {
159+
...inputArgs,
160+
data,
161+
};
162+
for (const validation of validations) {
163+
const validate =
164+
typeof validation === "object" ? validation.validate : validation;
132165
await validate(validationArgs);
133-
} catch (error) {
134-
isValid = false;
135-
errorMessage = getErrorMessage(error);
136-
break;
137166
}
167+
const result = {
168+
isValid: true,
169+
attempt,
170+
param,
171+
history: await history.list(),
172+
data,
173+
resultId,
174+
};
175+
if (outlineCallbacks?.onValidDocument) {
176+
outlineCallbacks.onValidDocument(result);
177+
}
178+
return result;
179+
} catch (error) {
180+
errorMessage = getErrorMessage(error);
138181
}
139-
if (!isValid) {
140-
continue;
141-
}
142-
const result = {
143-
isValid: true,
144-
attempt,
145-
param,
146-
history: await history.list(),
147-
data,
148-
resultId,
149-
};
150-
if (callbacks?.onValidDocument) {
151-
callbacks.onValidDocument(result);
152-
}
153-
return result;
154182
}
155183
const result = {
156184
isValid: false,
@@ -161,8 +189,8 @@ const jsonInternal = beginContext(
161189
data: null,
162190
resultId,
163191
};
164-
if (callbacks?.onInvalidDocument) {
165-
callbacks.onInvalidDocument(result);
192+
if (outlineCallbacks?.onInvalidDocument) {
193+
outlineCallbacks.onInvalidDocument(result);
166194
}
167195
return result;
168196
}

src/interfaces/Completion.interface.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { IModelMessage } from "../model/ModelMessage.model";
22
import { ITool } from "../model/Tool.model";
33
import { AgentName } from "./Agent.interface";
4+
import { IOutlineMessage, OutlineName } from "./Outline.interface";
45
import { ExecutionMode } from "./Session.interface";
56

67
/**
@@ -15,17 +16,34 @@ export interface ICompletion extends ICompletionSchema {}
1516
* Encapsulates context and inputs for generating a model response.
1617
*/
1718
export interface ICompletionArgs {
18-
/** The unique ID of the client requesting the completion. */
19-
clientId: string;
19+
/**
20+
* The unique identifier for the client making the request.
21+
* This is used to track the request and associate it with the correct client context.
22+
* For outline completions, this being skipped
23+
* @type {string}
24+
*/
25+
clientId?: string;
2026

21-
/** The unique name of the agent associated with the completion request. */
22-
agentName: AgentName;
27+
/**
28+
* The name of the agent for which the completion is requested.
29+
* This is used to identify the agent context in which the completion will be generated.
30+
* @type {AgentName}
31+
*/
32+
agentName?: AgentName;
33+
34+
/**
35+
* The outline used for json completions, if applicable.
36+
* This is the name of the outline schema that defines the structure of the expected JSON response.
37+
* Used to ensure that the completion adheres to the specified outline format.
38+
* @type {OutlineName}
39+
*/
40+
outlineName?: OutlineName;
2341

2442
/** The source of the last message, indicating whether it originated from a tool or user. */
2543
mode: ExecutionMode;
2644

2745
/** An array of model messages providing the conversation history or context for the completion. */
28-
messages: IModelMessage[];
46+
messages: (IModelMessage | IOutlineMessage)[];
2947

3048
/** Optional array of tools available for the completion process (e.g., for tool calls). */
3149
tools?: ITool[];
@@ -42,7 +60,7 @@ export interface ICompletionCallbacks {
4260
* @param {ICompletionArgs} args - The arguments used to generate the completion.
4361
* @param {IModelMessage} output - The model-generated message resulting from the completion.
4462
*/
45-
onComplete?: (args: ICompletionArgs, output: IModelMessage) => void;
63+
onComplete?: (args: ICompletionArgs, output: IModelMessage | IOutlineMessage) => void;
4664
}
4765

4866
/**
@@ -60,7 +78,14 @@ export interface ICompletionSchema {
6078
* @returns {Promise<IModelMessage>} A promise resolving to the generated model message.
6179
* @throws {Error} If completion generation fails (e.g., due to invalid arguments, model errors, or tool issues).
6280
*/
63-
getCompletion(args: ICompletionArgs): Promise<IModelMessage>;
81+
getCompletion(args: ICompletionArgs): Promise<IModelMessage | IOutlineMessage>;
82+
83+
/*
84+
* Flag if the completion is a JSON completion.
85+
* If true, the completion will be treated as a JSON object.
86+
* Should be used for completions that return structured data using Outlines.
87+
*/
88+
json?: boolean;
6489

6590
/** List of flags for llm model. As example, `/no_think` for `lmstudio-community/Qwen3-32B-GGUF` */
6691
flags?: string[];

src/interfaces/Outline.interface.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { IToolCall } from "../model/Tool.model";
2+
import { CompletionName } from "./Completion.interface";
3+
14
/**
25
* Generic type representing arbitrary param for outline operations.
36
* Used as a flexible placeholder for input param in outline schemas and arguments.
@@ -101,16 +104,29 @@ export interface IOutlineMessage {
101104
/**
102105
* The role of the message sender, either user, assistant, or system.
103106
* Determines the context or source of the message in the outline history.
104-
* @type {"user" | "assistant" | "system"}
107+
* @type {"assistant" | "system" | "tool" | "user"}
105108
*/
106-
role: "user" | "assistant" | "system";
109+
role: "assistant" | "system" | "tool" | "user";
107110

108111
/**
109112
* The content of the message.
110113
* Contains the raw text or param of the message, used in history storage or processing.
111114
* @type {string}
112115
*/
113116
content: string;
117+
118+
/**
119+
* The name of the agent associated with the message.
120+
* Allow to attach tool call request to specific message
121+
*/
122+
tool_calls?: IToolCall[];
123+
124+
/**
125+
* Optional ID of the tool call associated with the message.
126+
* Used to link the message to a specific tool execution request.
127+
* @type {string | undefined}
128+
*/
129+
tool_call_id?: string;
114130
}
115131

116132
/**
@@ -310,6 +326,9 @@ export interface IOutlineSchema<
310326
Param extends IOutlineParam = IOutlineParam
311327
> {
312328

329+
/** The name of the completion for JSON */
330+
completion: CompletionName;
331+
313332
/**
314333
* The prompt or prompt generator for the outline operation.
315334
* Can be a string, an array of strings, or a function that returns a string, array of strings, or a promise resolving to either.
@@ -339,7 +358,7 @@ export interface IOutlineSchema<
339358
* @param {IOutlineArgs<Param>} args - The arguments containing input param and history.
340359
* @returns {Promise<Data>} A promise resolving to the structured data.
341360
*/
342-
getStructuredOutput(args: IOutlineArgs<Param>): Promise<Data>;
361+
getOutlineHistory(args: IOutlineArgs<Param>): Promise<void>;
343362

344363
/**
345364
* Array of validation functions or configurations to apply to the outline data.

src/lib/services/base/DocService.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,13 @@ export class DocService {
430430
result.push("");
431431
}
432432

433+
if (outlineSchema.completion) {
434+
result.push(
435+
`**Completion:** \`${sanitizeMarkdown(outlineSchema.completion)}\``
436+
);
437+
result.push("");
438+
}
439+
433440
const getPrompt = async () => {
434441
try {
435442
if (typeof outlineSchema.prompt === "string") {

0 commit comments

Comments
 (0)