Merge remote-tracking branch 'origin/master' into jason_dev
This commit is contained in:
commit
515783e21d
|
|
@ -5,7 +5,7 @@ public interface IKnowledgeHook
|
|||
Task<List<KnowledgeChunk>> CollectChunkedKnowledge()
|
||||
=> Task.FromResult(new List<KnowledgeChunk>());
|
||||
|
||||
Task<List<string>> GetRelevantKnowledges()
|
||||
Task<List<string>> GetRelevantKnowledges(string text)
|
||||
=> Task.FromResult(new List<string>());
|
||||
|
||||
Task<List<string>> GetGlobalKnowledges()
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public interface IKnowledgeService
|
|||
Task<bool> DeleteVectorCollectionAllData(string collectionName);
|
||||
Task<bool> CreateVectorCollectionData(string collectionName, VectorCreateModel create);
|
||||
Task<bool> UpdateVectorCollectionData(string collectionName, VectorUpdateModel update);
|
||||
Task<bool> UpsertVectorCollectionData(string collectionName, VectorUpdateModel update);
|
||||
#endregion
|
||||
|
||||
#region Graph
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ public class GenericTemplateMessage<T> : IRichMessage, ITemplateMessage
|
|||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => RichTypeEnum.GenericTemplate;
|
||||
|
||||
/// <summary>
|
||||
/// Use model refined content if leaving blank
|
||||
/// </summary>
|
||||
[JsonPropertyName("text")]
|
||||
[Translate]
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ public interface IPlanningHook
|
|||
{
|
||||
Task<string> GetSummaryAdditionalRequirements(string planner)
|
||||
=> Task.FromResult(string.Empty);
|
||||
|
||||
Task OnPlanningCompleted(string planner, RoleDialogModel msg)
|
||||
=> Task.CompletedTask;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,5 +5,7 @@ public class VectorCollectionData
|
|||
public string Id { get; set; }
|
||||
public Dictionary<string, string> Data { get; set; } = new();
|
||||
public double? Score { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public float[]? Vector { get; set; }
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
using BotSharp.Abstraction.Knowledges.Enums;
|
||||
|
||||
namespace BotSharp.Abstraction.VectorStorage.Models;
|
||||
|
||||
public class VectorSearchResult : VectorCollectionData
|
||||
|
|
|
|||
|
|
@ -123,6 +123,12 @@ public partial class ConversationService
|
|||
Message = new TextMessage(response.SecondaryContent ?? response.Content)
|
||||
};
|
||||
|
||||
// Use model refined response
|
||||
if (string.IsNullOrEmpty(response.RichContent.Message.Text))
|
||||
{
|
||||
response.RichContent.Message.Text = response.Content;
|
||||
}
|
||||
|
||||
// Patch return function name
|
||||
if (response.PostbackFunctionName != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@
|
|||
<OutputPath>$(SolutionDir)packages</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="packages\**" />
|
||||
<EmbeddedResource Remove="packages\**" />
|
||||
<None Remove="packages\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\arts\Icon.png">
|
||||
<Pack>True</Pack>
|
||||
|
|
|
|||
|
|
@ -31,8 +31,12 @@ namespace BotSharp.OpenAPI.Filters
|
|||
return;
|
||||
}
|
||||
|
||||
if (token.ValidTo.ToLongTimeString() != GetUserExpires().ToLongTimeString())
|
||||
var validTo = token.ValidTo.ToLongTimeString();
|
||||
var currentExpires = GetUserExpires().ToLongTimeString();
|
||||
|
||||
if (validTo != currentExpires)
|
||||
{
|
||||
Serilog.Log.Warning($"Token expired. Token expires at {validTo}, current expires at {currentExpires}");
|
||||
context.Result = new UnauthorizedResult();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,6 +164,42 @@ public partial class KnowledgeService
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<bool> UpsertVectorCollectionData(string collectionName, VectorUpdateModel update)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(collectionName) || string.IsNullOrWhiteSpace(update.Text) || !Guid.TryParse(update.Id, out var guid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var db = GetVectorDb();
|
||||
var found = await db.GetCollectionData(collectionName, new List<Guid> { guid },
|
||||
withVector: true,
|
||||
withPayload: true);
|
||||
if (!found.IsNullOrEmpty())
|
||||
{
|
||||
if (found.First().Data["text"] == update.Text)
|
||||
{
|
||||
// Only update payload
|
||||
return await db.Upsert(collectionName, guid, found.First().Vector, update.Text, update.Payload);
|
||||
}
|
||||
}
|
||||
|
||||
var textEmbedding = GetTextEmbedding(collectionName);
|
||||
var vector = await textEmbedding.GetVectorAsync(update.Text);
|
||||
var payload = update.Payload ?? new();
|
||||
payload[KnowledgePayloadName.DataSource] = !string.IsNullOrWhiteSpace(update.DataSource) ? update.DataSource : VectorDataSource.Api;
|
||||
|
||||
return await db.Upsert(collectionName, guid, vector, update.Text, payload);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning($"Error when updating vector collection data. {ex.Message}\r\n{ex.InnerException}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteVectorCollectionData(string collectionName, string id)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public class PrimaryStagePlanFn : IFunctionCallback
|
|||
var collectionName = knowledgeSettings.Default.CollectionName ?? KnowledgeCollectionName.BotSharp;
|
||||
|
||||
// Get knowledge from vectordb
|
||||
var hooks = _services.GetServices<IKnowledgeHook>();
|
||||
var knowledges = new List<string>();
|
||||
foreach (var question in task.Questions)
|
||||
{
|
||||
|
|
@ -34,8 +35,13 @@ public class PrimaryStagePlanFn : IFunctionCallback
|
|||
{
|
||||
Confidence = 0.2f
|
||||
});
|
||||
|
||||
knowledges.Add(string.Join("\r\n\r\n=====\r\n", list.Select(x => x.ToQuestionAnswer())));
|
||||
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
var k = await hook.GetRelevantKnowledges(question);
|
||||
knowledges.AddRange(k);
|
||||
}
|
||||
}
|
||||
|
||||
// Get first stage planning prompt
|
||||
|
|
@ -92,7 +98,7 @@ public class PrimaryStagePlanFn : IFunctionCallback
|
|||
var wholeDialogs = conv.GetDialogHistory();
|
||||
|
||||
// Append text
|
||||
wholeDialogs.Last().Content += "\n\nYou must analyze the table description to infer the table relations.";
|
||||
wholeDialogs.Last().Content += "\n\nYou must analyze the table description to infer the table relations. Only output the JSON result.";
|
||||
|
||||
var completion = CompletionProvider.GetChatCompletion(_services,
|
||||
provider: plannerAgent.LlmConfig.Provider,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ public class SecondaryStagePlanFn : IFunctionCallback
|
|||
var template = agent.Templates.FirstOrDefault(x => x.Name == "two_stage.2nd.plan")?.Content ?? string.Empty;
|
||||
var responseFormat = JsonSerializer.Serialize(new SecondStagePlan
|
||||
{
|
||||
Tool = "tool name if task solution provided",
|
||||
Parameters = [ JsonDocument.Parse("{}") ],
|
||||
Results = [ string.Empty ]
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@ public class SecondStagePlan
|
|||
[JsonPropertyName("description")]
|
||||
public string Description { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("tool_name")]
|
||||
public string Tool { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("input_args")]
|
||||
public JsonDocument[] Parameters { get; set; } = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -96,31 +96,6 @@ public partial class TwoStageTaskPlanner : IRoutingPlaner
|
|||
return true;
|
||||
}
|
||||
|
||||
private async Task<string> GetFirstStagePlanPrompt(Agent router)
|
||||
{
|
||||
var template = router.Templates.First(x => x.Name == "two_stage.1st.plan").Content;
|
||||
var responseFormat = JsonSerializer.Serialize(new FirstStagePlan
|
||||
{
|
||||
Parameters = new JsonDocument[] { JsonDocument.Parse("{}") },
|
||||
Results = new string[] { "" }
|
||||
});
|
||||
|
||||
var relevantKnowledges = new List<string>();
|
||||
var hooks = _services.GetServices<IKnowledgeHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
var k = await hook.GetRelevantKnowledges();
|
||||
relevantKnowledges.AddRange(k);
|
||||
}
|
||||
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
return render.Render(template, new Dictionary<string, object>
|
||||
{
|
||||
{ "response_format", responseFormat },
|
||||
{ "relevant_knowledges", relevantKnowledges.ToArray() }
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<string> GetNextStepPrompt(Agent router)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
|
|
@ -134,17 +109,4 @@ public partial class TwoStageTaskPlanner : IRoutingPlaner
|
|||
{ StateConst.EXPECTED_GOAL_AGENT, states.GetState(StateConst.EXPECTED_GOAL_AGENT) }
|
||||
});
|
||||
}
|
||||
|
||||
private string GetSecondStageTaskPrompt(Agent router, SecondStagePlan plan)
|
||||
{
|
||||
var template = router.Templates.First(x => x.Name == "planner_prompt.two_stage.2nd.task").Content;
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
return render.Render(template, new Dictionary<string, object>
|
||||
{
|
||||
{ "task_description", plan.Description },
|
||||
{ "related_tables", plan.Tables },
|
||||
{ "input_arguments", JsonSerializer.Serialize(plan.Parameters) },
|
||||
{ "output_results", JsonSerializer.Serialize(plan.Results) },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
Use the TwoStagePlanner approach to plan the overall implementation steps, follow the below steps strictly.
|
||||
1. call plan_primary_stage to generate the primary plan.
|
||||
1. Call plan_primary_stage to generate the primary plan.
|
||||
2. If need_additional_information is true, call plan_secondary_stage for the specific primary stage.
|
||||
3. You must call plan_summary for you final planned output.
|
||||
3. You must call plan_summary to generate final planned steps.
|
||||
4. If you can't generate the final accurate planning steps due to missing some specific informations, please ask user for more information.
|
||||
|
||||
*** IMPORTANT ***
|
||||
Don't run the planning process repeatedly if you have already got the result of user's request.
|
||||
|
|
|
|||
|
|
@ -10,4 +10,3 @@ Expected user goal agent is {{ expected_user_goal_agent }}.
|
|||
{%- else -%}
|
||||
User goal agent is inferred based on user initial request.
|
||||
{%- endif %}
|
||||
Always route to planner first.
|
||||
|
|
@ -29,7 +29,15 @@ public class ExecuteQueryFn : IFunctionCallback
|
|||
_ => throw new NotImplementedException($"Database type {settings.DatabaseType} is not supported.")
|
||||
};
|
||||
|
||||
message.Content = JsonSerializer.Serialize(results);
|
||||
if (results.Count() == 0)
|
||||
{
|
||||
message.Content = "No record found";
|
||||
}
|
||||
else
|
||||
{
|
||||
message.Content = JsonSerializer.Serialize(results);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue