shark-ai 0.4.5 → 0.4.7
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/bin/shark.js +171 -144
- package/dist/bin/shark.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/shark.js
CHANGED
|
@@ -1008,6 +1008,20 @@ var TypeScriptEditor = class {
|
|
|
1008
1008
|
return false;
|
|
1009
1009
|
}
|
|
1010
1010
|
}
|
|
1011
|
+
async getProperty(filePath, className, propertyName) {
|
|
1012
|
+
try {
|
|
1013
|
+
const sourceFile = this.getSourceFile(filePath);
|
|
1014
|
+
const classDecl = this.getClass(sourceFile, className);
|
|
1015
|
+
const property = classDecl.getProperty(propertyName);
|
|
1016
|
+
if (!property) {
|
|
1017
|
+
return void 0;
|
|
1018
|
+
}
|
|
1019
|
+
return property.getText();
|
|
1020
|
+
} catch (error) {
|
|
1021
|
+
console.error(`Failed to get property "${propertyName}":`, error);
|
|
1022
|
+
return void 0;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1011
1025
|
async modifyProperty(filePath, className, propertyName, newCode) {
|
|
1012
1026
|
try {
|
|
1013
1027
|
const sourceFile = this.getSourceFile(filePath);
|
|
@@ -1703,95 +1717,141 @@ function getAgentId2(overrideId) {
|
|
|
1703
1717
|
}
|
|
1704
1718
|
async function interactiveSpecificationAgent(options = {}) {
|
|
1705
1719
|
FileLogger.init();
|
|
1706
|
-
tui.intro("\u{1F3D7}\uFE0F Specification Agent");
|
|
1720
|
+
tui.intro("\u{1F3D7}\uFE0F Specification Agent (Template-Based)");
|
|
1707
1721
|
const projectRoot = process.cwd();
|
|
1722
|
+
const sharkRcDir = path6.resolve(projectRoot, "_sharkrc");
|
|
1723
|
+
if (!fs5.existsSync(sharkRcDir)) fs5.mkdirSync(sharkRcDir, { recursive: true });
|
|
1724
|
+
const outputFile = path6.resolve(sharkRcDir, "tech-spec.md");
|
|
1725
|
+
if (!fs5.existsSync(outputFile)) {
|
|
1726
|
+
let initialContent = `# Technical Specification: {{PROJECT_NAME}}
|
|
1727
|
+
|
|
1728
|
+
## 1. Technology Stack
|
|
1729
|
+
[TO BE ANALYZED]
|
|
1730
|
+
- Language: [e.g. TypeScript]
|
|
1731
|
+
- Framework: [e.g. Node.js / React]
|
|
1732
|
+
- Database: [e.g. SQLite / PostgreSQL]
|
|
1733
|
+
- Key Libraries: [Top 5 dependencies]
|
|
1734
|
+
|
|
1735
|
+
## 2. Architecture Overview
|
|
1736
|
+
[TO BE ANALYZED]
|
|
1737
|
+
[Brief description of architectural pattern]
|
|
1738
|
+
|
|
1739
|
+
## 3. Data Model
|
|
1740
|
+
[TO BE ANALYZED]
|
|
1741
|
+
[Schema/ERD definitions]
|
|
1742
|
+
|
|
1743
|
+
## 4. API / Interface Contracts
|
|
1744
|
+
[TO BE ANALYZED]
|
|
1745
|
+
[Main endpoints or CLI commands]
|
|
1746
|
+
|
|
1747
|
+
## 5. Implementation Steps
|
|
1748
|
+
[TO BE FILLED - MUST BE CHECKBOXES]
|
|
1749
|
+
`;
|
|
1750
|
+
const projectName = path6.basename(projectRoot);
|
|
1751
|
+
initialContent = initialContent.replace(/{{PROJECT_NAME}}/g, projectName);
|
|
1752
|
+
const BOM = "\uFEFF";
|
|
1753
|
+
fs5.writeFileSync(outputFile, BOM + initialContent, { encoding: "utf-8" });
|
|
1754
|
+
tui.log.success(`\u2705 Created: ${colors.bold("_sharkrc/tech-spec.md")}`);
|
|
1755
|
+
} else {
|
|
1756
|
+
tui.log.info(`\u{1F4C4} Using existing ${colors.bold("_sharkrc/tech-spec.md")}`);
|
|
1757
|
+
}
|
|
1708
1758
|
let contextContent = "";
|
|
1709
1759
|
const contextPath = path6.resolve(projectRoot, "_sharkrc", "project-context.md");
|
|
1710
1760
|
if (fs5.existsSync(contextPath)) {
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
tui.log.info(`\u{1F4D8} Context loaded from: ${colors.dim(path6.relative(projectRoot, contextPath))}`);
|
|
1714
|
-
} catch (e) {
|
|
1715
|
-
tui.log.warning(`Failed to read context file: ${e}`);
|
|
1716
|
-
}
|
|
1761
|
+
contextContent = fs5.readFileSync(contextPath, "utf-8");
|
|
1762
|
+
tui.log.info(`\u{1F4D8} Context loaded.`);
|
|
1717
1763
|
}
|
|
1718
1764
|
let briefingContent = "";
|
|
1719
1765
|
if (options.briefingPath && fs5.existsSync(options.briefingPath)) {
|
|
1720
1766
|
briefingContent = fs5.readFileSync(options.briefingPath, "utf-8");
|
|
1721
1767
|
tui.log.info(`\u{1F4C4} Briefing loaded from: ${colors.dim(options.briefingPath)}`);
|
|
1722
1768
|
} else {
|
|
1723
|
-
const
|
|
1724
|
-
if (fs5.existsSync(
|
|
1725
|
-
briefingContent = fs5.readFileSync(
|
|
1726
|
-
tui.log.info(`\u{1F4C4}
|
|
1727
|
-
} else {
|
|
1728
|
-
tui.log.info(colors.dim("\u2139\uFE0F No briefing file found in _sharkrc/briefing.md. Starting in interactive mode."));
|
|
1769
|
+
const standardBriefing = path6.resolve(projectRoot, "_sharkrc", "briefing.md");
|
|
1770
|
+
if (fs5.existsSync(standardBriefing)) {
|
|
1771
|
+
briefingContent = fs5.readFileSync(standardBriefing, "utf-8");
|
|
1772
|
+
tui.log.info(`\u{1F4C4} Briefing loaded.`);
|
|
1729
1773
|
}
|
|
1730
1774
|
}
|
|
1731
|
-
let initialPrompt =
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1775
|
+
let initialPrompt = `
|
|
1776
|
+
You are the **Shark Spec Agent**, a Senior Software Architect.
|
|
1777
|
+
Your goal is to COMPLETE the technical specification file \`_sharkrc/tech-spec.md\`.
|
|
1778
|
+
|
|
1779
|
+
**CURRENT STATE:**
|
|
1780
|
+
The file \`_sharkrc/tech-spec.md\` exists. It contains placeholders like \`[TO BE ANALYZED]\` or \`[TO BE FILLED]\`.
|
|
1781
|
+
|
|
1782
|
+
**YOUR MISSION:**
|
|
1783
|
+
Iteratively analyze the project and fill in these placeholders.
|
|
1784
|
+
|
|
1785
|
+
**INPUTS:**
|
|
1740
1786
|
`;
|
|
1741
|
-
}
|
|
1742
1787
|
if (briefingContent) {
|
|
1743
1788
|
initialPrompt += `
|
|
1744
|
-
Abaixo est\xE1 o **Briefing de Neg\xF3cio** ou Descri\xE7\xE3o da Tarefa.
|
|
1745
|
-
Analise-o e ajude-me a definir a Especifica\xE7\xE3o T\xE9cnica (tech-spec.md).
|
|
1746
|
-
|
|
1747
1789
|
--- BRIEFING ---
|
|
1748
1790
|
${briefingContent}
|
|
1749
1791
|
----------------
|
|
1750
1792
|
`;
|
|
1751
1793
|
} else {
|
|
1752
1794
|
initialPrompt += `
|
|
1753
|
-
|
|
1754
|
-
|
|
1795
|
+
(No formal briefing provided. Ask the user for requirements if needed.)
|
|
1796
|
+
`;
|
|
1797
|
+
}
|
|
1798
|
+
if (options.initialContext) {
|
|
1799
|
+
initialPrompt += `
|
|
1800
|
+
--- HANDOVER CONTEXT (PREVIOUS FAILURES/FEEDBACK) ---
|
|
1801
|
+
${options.initialContext}
|
|
1802
|
+
-----------------------------------------------------
|
|
1755
1803
|
`;
|
|
1756
1804
|
}
|
|
1757
1805
|
if (contextContent) {
|
|
1758
1806
|
initialPrompt += `
|
|
1759
|
-
Abaixo est\xE1 o **Contexto do Projeto** atual. Use-o para alinhar a especifica\xE7\xE3o com a arquitetura existente.
|
|
1760
|
-
|
|
1761
1807
|
--- PROJECT CONTEXT ---
|
|
1762
1808
|
${contextContent}
|
|
1763
1809
|
-----------------------
|
|
1764
1810
|
`;
|
|
1765
1811
|
}
|
|
1766
1812
|
initialPrompt += `
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1813
|
+
**RULES OF ENGAGEMENT (STRICT):**
|
|
1814
|
+
|
|
1815
|
+
1. **INCREMENTAL WORK**: Do NOT try to write the whole file at once. Focus on one section at a time.
|
|
1816
|
+
2. **READ BEFORE WRITING**:
|
|
1817
|
+
- Before filling **Tech Stack** or **Architecture**, run \`list_files\` and \`read_file\` to verify existing code.
|
|
1818
|
+
- Before adding **Implementation Steps**, you MUST read the target files referenced in the tasks.
|
|
1819
|
+
- **PROHIBITED**: Adding a task like "- [ ] Modify src/auth.ts" without having read "src/auth.ts" first (unless it's a new file).
|
|
1820
|
+
|
|
1821
|
+
3. **TASK FORMAT for 'Implementation Steps'**:
|
|
1822
|
+
- MUST be Markdown Checkboxes: \`- [ ] ...\`
|
|
1823
|
+
- MUST be simple, atomic lines. NO indentation.
|
|
1824
|
+
- Format: \`- [ ] [Action verb] [What] in [Rel Path]\`
|
|
1825
|
+
- Example: \`- [ ] Add validation function to src/utils/validators.ts\`
|
|
1826
|
+
|
|
1827
|
+
4. **USER INTERACTION**:
|
|
1828
|
+
- If requirements are vague, use \`talk_with_user\` to clarify BEFORE defining tasks.
|
|
1829
|
+
|
|
1830
|
+
**STRATEGY:**
|
|
1831
|
+
1. Check \`_sharkrc/tech-spec.md\` content (I will provide snippets of what's missing).
|
|
1832
|
+
2. Explore necessary files.
|
|
1833
|
+
3. Update \`_sharkrc/tech-spec.md\` using \`modify_file\` to replace placeholders.
|
|
1834
|
+
4. Repeat untill all placeholders are gone.
|
|
1786
1835
|
`;
|
|
1787
|
-
await runSpecLoop(initialPrompt.trim(), options.agentId);
|
|
1836
|
+
await runSpecLoop(initialPrompt.trim(), outputFile, options.agentId);
|
|
1788
1837
|
}
|
|
1789
|
-
async function runSpecLoop(initialMessage, overrideAgentId) {
|
|
1838
|
+
async function runSpecLoop(initialMessage, targetPath, overrideAgentId) {
|
|
1790
1839
|
let nextPrompt = initialMessage;
|
|
1791
1840
|
let keepGoing = true;
|
|
1792
|
-
|
|
1841
|
+
let stepCount = 0;
|
|
1842
|
+
const MAX_STEPS = 30;
|
|
1843
|
+
while (keepGoing && stepCount < MAX_STEPS) {
|
|
1844
|
+
stepCount++;
|
|
1793
1845
|
const spinner = tui.spinner();
|
|
1794
|
-
spinner.start(
|
|
1846
|
+
spinner.start(`\u{1F3D7}\uFE0F Spec Agent working (Step ${stepCount}/${MAX_STEPS})...`);
|
|
1847
|
+
let pendingSections = [];
|
|
1848
|
+
if (fs5.existsSync(targetPath)) {
|
|
1849
|
+
const content = fs5.readFileSync(targetPath, "utf-8");
|
|
1850
|
+
if (content.includes("[TO BE ANALYZED]")) pendingSections.push("Analysis Sections (Stack, Arch, Data, API)");
|
|
1851
|
+
if (content.includes("[TO BE FILLED")) pendingSections.push("Implementation Steps");
|
|
1852
|
+
}
|
|
1853
|
+
if (pendingSections.length === 0 && stepCount > 1) {
|
|
1854
|
+
}
|
|
1795
1855
|
let responseText = "";
|
|
1796
1856
|
let lastResponse = null;
|
|
1797
1857
|
try {
|
|
@@ -1802,10 +1862,10 @@ async function runSpecLoop(initialMessage, overrideAgentId) {
|
|
|
1802
1862
|
if (lastResponse && lastResponse.actions) {
|
|
1803
1863
|
let executionResults = "";
|
|
1804
1864
|
let waitingForUser = false;
|
|
1865
|
+
let specUpdated = false;
|
|
1805
1866
|
if (lastResponse.message && lastResponse.message.includes("SPEC_UPDATED:")) {
|
|
1806
1867
|
const updateSummary = lastResponse.message.split("SPEC_UPDATED:")[1].trim();
|
|
1807
|
-
tui.log.success(`\u2705 Spec
|
|
1808
|
-
tui.log.info("\u{1F4CB} Returning to orchestration loop...");
|
|
1868
|
+
tui.log.success(`\u2705 Spec Finalized: ${updateSummary}`);
|
|
1809
1869
|
return;
|
|
1810
1870
|
}
|
|
1811
1871
|
for (const action of lastResponse.actions) {
|
|
@@ -1834,97 +1894,78 @@ ${result}
|
|
|
1834
1894
|
${result}
|
|
1835
1895
|
|
|
1836
1896
|
`;
|
|
1837
|
-
} else if (["create_file", "modify_file"
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1897
|
+
} else if (["create_file", "modify_file"].includes(action.type)) {
|
|
1898
|
+
let actionPath = path6.resolve(action.path || "");
|
|
1899
|
+
const resolvedTargetPath = path6.resolve(targetPath);
|
|
1900
|
+
let isTarget = actionPath === resolvedTargetPath;
|
|
1901
|
+
if (!isTarget && path6.basename(actionPath) === "tech-spec.md") {
|
|
1902
|
+
tui.log.warning(`Redirecting ${action.type} from ${action.path} to ${path6.relative(process.cwd(), targetPath)}`);
|
|
1903
|
+
action.path = targetPath;
|
|
1904
|
+
actionPath = resolvedTargetPath;
|
|
1905
|
+
isTarget = true;
|
|
1843
1906
|
}
|
|
1844
|
-
|
|
1845
|
-
message: `
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
});
|
|
1849
|
-
if (confirm) {
|
|
1850
|
-
if (action.path) {
|
|
1851
|
-
try {
|
|
1852
|
-
if (action.type === "create_file") {
|
|
1853
|
-
const BOM = "\uFEFF";
|
|
1854
|
-
const contentToWrite = action.content || "";
|
|
1855
|
-
const finalContent = contentToWrite.startsWith(BOM) ? contentToWrite : BOM + contentToWrite;
|
|
1856
|
-
const dir = path6.dirname(action.path);
|
|
1857
|
-
if (!fs5.existsSync(dir)) fs5.mkdirSync(dir, { recursive: true });
|
|
1858
|
-
fs5.writeFileSync(action.path, finalContent, { encoding: "utf-8" });
|
|
1859
|
-
tui.log.success(`\u2705 Created: ${action.path}`);
|
|
1860
|
-
executionResults += `[Action create_file(${action.path})]: Success
|
|
1861
|
-
|
|
1907
|
+
if (!isTarget && action.type === "create_file") {
|
|
1908
|
+
const confirm = await tui.confirm({ message: `Agent wants to create ${action.path}. Allow?` });
|
|
1909
|
+
if (!confirm) {
|
|
1910
|
+
executionResults += `[Action create_file]: User denied.
|
|
1862
1911
|
`;
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1912
|
+
continue;
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
try {
|
|
1916
|
+
if (action.type === "create_file") {
|
|
1917
|
+
const BOM = "\uFEFF";
|
|
1918
|
+
fs5.writeFileSync(action.path, BOM + (action.content || ""), "utf-8");
|
|
1919
|
+
tui.log.success(`\u2705 Created: ${action.path}`);
|
|
1920
|
+
executionResults += `[Action create_file]: Success.
|
|
1868
1921
|
`;
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1922
|
+
} else if (action.type === "modify_file") {
|
|
1923
|
+
if (action.target_content) {
|
|
1924
|
+
const success = startSmartReplace(action.path, action.content || "", action.target_content, tui);
|
|
1925
|
+
if (success) {
|
|
1926
|
+
executionResults += `[Action modify_file]: Success.
|
|
1873
1927
|
`;
|
|
1874
|
-
|
|
1875
|
-
} else
|
|
1876
|
-
|
|
1877
|
-
tui.log.success(`\u2705 Deleted: ${action.path}`);
|
|
1878
|
-
executionResults += `[Action delete_file(${action.path})]: Success
|
|
1879
|
-
|
|
1928
|
+
specUpdated = true;
|
|
1929
|
+
} else {
|
|
1930
|
+
executionResults += `[Action modify_file]: Failed. Target content not found.
|
|
1880
1931
|
`;
|
|
1881
1932
|
}
|
|
1882
|
-
}
|
|
1883
|
-
|
|
1884
|
-
executionResults += `[Action ${action.type}(${action.path})]: Error: ${e.message}
|
|
1885
|
-
|
|
1933
|
+
} else {
|
|
1934
|
+
executionResults += `[Action modify_file]: Failed. 'target_content' is required.
|
|
1886
1935
|
`;
|
|
1887
1936
|
}
|
|
1888
1937
|
}
|
|
1889
|
-
}
|
|
1890
|
-
|
|
1891
|
-
executionResults += `[Action ${action.type}]: User Denied
|
|
1892
|
-
|
|
1938
|
+
} catch (e) {
|
|
1939
|
+
executionResults += `[Action ${action.type}]: Error: ${e.message}
|
|
1893
1940
|
`;
|
|
1894
1941
|
}
|
|
1895
1942
|
}
|
|
1896
1943
|
}
|
|
1897
|
-
if (
|
|
1898
|
-
|
|
1899
|
-
const userReply = await tui.text({
|
|
1900
|
-
message: "Your answer",
|
|
1901
|
-
placeholder: "Type your answer..."
|
|
1902
|
-
});
|
|
1903
|
-
if (tui.isCancel(userReply)) {
|
|
1904
|
-
keepGoing = false;
|
|
1905
|
-
return;
|
|
1906
|
-
}
|
|
1907
|
-
nextPrompt = `${executionResults}
|
|
1908
|
-
|
|
1909
|
-
User Reply: ${userReply}`;
|
|
1910
|
-
} else {
|
|
1911
|
-
nextPrompt = executionResults;
|
|
1912
|
-
FileLogger.log("SYSTEM", "Auto-replying with Tool Results", { length: executionResults.length });
|
|
1913
|
-
tui.log.info(colors.dim("Processing tool results..."));
|
|
1914
|
-
}
|
|
1915
|
-
} else if (waitingForUser) {
|
|
1916
|
-
const userReply = await tui.text({
|
|
1917
|
-
message: "Your answer",
|
|
1918
|
-
placeholder: "Type your answer..."
|
|
1919
|
-
});
|
|
1944
|
+
if (waitingForUser) {
|
|
1945
|
+
const userReply = await tui.text({ message: "Your answer", placeholder: "Type your answer..." });
|
|
1920
1946
|
if (tui.isCancel(userReply)) {
|
|
1921
1947
|
keepGoing = false;
|
|
1922
1948
|
return;
|
|
1923
1949
|
}
|
|
1924
|
-
nextPrompt =
|
|
1950
|
+
nextPrompt = `${executionResults}
|
|
1951
|
+
|
|
1952
|
+
User Reply: ${userReply}`;
|
|
1953
|
+
} else if (executionResults) {
|
|
1954
|
+
const content = fs5.existsSync(targetPath) ? fs5.readFileSync(targetPath, "utf-8") : "";
|
|
1955
|
+
let systemMsg = "Tool execution completed.";
|
|
1956
|
+
if (specUpdated) {
|
|
1957
|
+
if (content.includes("[TO BE")) {
|
|
1958
|
+
systemMsg += "\n[System]: Section updated. Please continue harmonizing and filling the remaining '[TO BE ...]' placeholders.";
|
|
1959
|
+
} else {
|
|
1960
|
+
systemMsg += "\n[System]: file looks complete! If you are satisfied, output 'SPEC_UPDATED: Complete'.";
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
nextPrompt = `${executionResults}
|
|
1964
|
+
|
|
1965
|
+
${systemMsg}`;
|
|
1925
1966
|
} else {
|
|
1926
1967
|
if (lastResponse.message) {
|
|
1927
|
-
tui.log.info(colors.primary("\u{1F916} Architect:"));
|
|
1968
|
+
tui.log.info(colors.primary("\u{1F916} Architect (Message only):"));
|
|
1928
1969
|
console.log(lastResponse.message);
|
|
1929
1970
|
const userReply = await tui.text({ message: "Your answer:" });
|
|
1930
1971
|
if (tui.isCancel(userReply)) {
|
|
@@ -1933,12 +1974,11 @@ User Reply: ${userReply}`;
|
|
|
1933
1974
|
}
|
|
1934
1975
|
nextPrompt = userReply;
|
|
1935
1976
|
} else {
|
|
1936
|
-
tui.log.warning("No actions taken.");
|
|
1937
1977
|
keepGoing = false;
|
|
1938
1978
|
}
|
|
1939
1979
|
}
|
|
1940
1980
|
} else {
|
|
1941
|
-
tui.log.warning("No actions received
|
|
1981
|
+
tui.log.warning("No actions received.");
|
|
1942
1982
|
keepGoing = false;
|
|
1943
1983
|
}
|
|
1944
1984
|
} catch (error) {
|
|
@@ -1964,12 +2004,7 @@ async function callSpecAgentApi(prompt, onChunk, agentId) {
|
|
|
1964
2004
|
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;
|
|
1965
2005
|
let fullMsg = "";
|
|
1966
2006
|
let raw = {};
|
|
1967
|
-
FileLogger.log("AGENT", "Calling Agent API", {
|
|
1968
|
-
agentId: effectiveAgentId,
|
|
1969
|
-
conversationId,
|
|
1970
|
-
prompt: prompt.substring(0, 500)
|
|
1971
|
-
// Log summary of prompt
|
|
1972
|
-
});
|
|
2007
|
+
FileLogger.log("AGENT", "Calling Agent API", { agentId: effectiveAgentId, conversationId });
|
|
1973
2008
|
await sseClient.streamAgentResponse(url, payload, { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" }, {
|
|
1974
2009
|
onChunk: (c) => {
|
|
1975
2010
|
fullMsg += c;
|
|
@@ -1977,15 +2012,7 @@ async function callSpecAgentApi(prompt, onChunk, agentId) {
|
|
|
1977
2012
|
},
|
|
1978
2013
|
onComplete: (msg, metadata) => {
|
|
1979
2014
|
const returnedId = metadata?.conversation_id;
|
|
1980
|
-
|
|
1981
|
-
conversationId,
|
|
1982
|
-
returnedId,
|
|
1983
|
-
messageLength: msg?.length
|
|
1984
|
-
});
|
|
1985
|
-
raw = {
|
|
1986
|
-
message: msg || fullMsg,
|
|
1987
|
-
conversation_id: returnedId || conversationId
|
|
1988
|
-
};
|
|
2015
|
+
raw = { message: msg || fullMsg, conversation_id: returnedId || conversationId };
|
|
1989
2016
|
},
|
|
1990
2017
|
onError: (e) => {
|
|
1991
2018
|
throw e;
|