@flutchai/flutch-sdk 0.2.11 → 0.2.15
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 +37 -0
- package/dist/index.cjs +44 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +44 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -522,6 +522,43 @@ Currently supports LangGraph.js. The architecture is designed to support other g
|
|
|
522
522
|
- **Multi-step Workflows**: Orchestrate complex AI pipelines
|
|
523
523
|
- **Interactive Assistants**: Create agents with callbacks and dynamic UIs
|
|
524
524
|
|
|
525
|
+
## Publishing
|
|
526
|
+
|
|
527
|
+
The package is automatically published to [npmjs.org](https://www.npmjs.com/package/@flutchai/flutch-sdk) on every merge to `main` via GitHub Actions.
|
|
528
|
+
|
|
529
|
+
### How it works
|
|
530
|
+
|
|
531
|
+
1. On merge to `main`, the [release workflow](.github/workflows/release.yml) runs
|
|
532
|
+
2. It reads the version from `package.json`
|
|
533
|
+
3. If a git tag `v{version}` does not exist yet — it creates the tag and publishes to npm
|
|
534
|
+
4. If the tag already exists — all publish steps are skipped (idempotent)
|
|
535
|
+
|
|
536
|
+
Publishing uses [npm OIDC Trusted Publishing](https://docs.npmjs.com/generating-provenance-statements) — no npm token secret is required. The GitHub Actions runner authenticates directly with npmjs.org via OpenID Connect.
|
|
537
|
+
|
|
538
|
+
### Rules
|
|
539
|
+
|
|
540
|
+
- **Bump the version before merging** — if `package.json` version matches an existing git tag, nothing will be published
|
|
541
|
+
- **Use semantic versioning** — `MAJOR.MINOR.PATCH` (e.g. `0.2.14`)
|
|
542
|
+
- `PATCH` — bug fixes, minor improvements
|
|
543
|
+
- `MINOR` — new backward-compatible features
|
|
544
|
+
- `MAJOR` — breaking changes
|
|
545
|
+
- **One version bump per PR** — keep version changes isolated from feature/fix changes when possible
|
|
546
|
+
|
|
547
|
+
### Releasing a new version
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
# 1. Create a branch
|
|
551
|
+
git checkout -b chore/bump-version-X.Y.Z
|
|
552
|
+
|
|
553
|
+
# 2. Update version in package.json
|
|
554
|
+
# "version": "X.Y.Z"
|
|
555
|
+
|
|
556
|
+
# 3. Push and open a PR
|
|
557
|
+
git push origin chore/bump-version-X.Y.Z
|
|
558
|
+
|
|
559
|
+
# 4. Merge the PR — publishing happens automatically
|
|
560
|
+
```
|
|
561
|
+
|
|
525
562
|
## Links
|
|
526
563
|
|
|
527
564
|
- [GitHub Repository](https://github.com/flutchai/node-sdk)
|
package/dist/index.cjs
CHANGED
|
@@ -4477,11 +4477,17 @@ async function executeToolWithAttachments(params) {
|
|
|
4477
4477
|
threshold = DEFAULT_ATTACHMENT_THRESHOLD,
|
|
4478
4478
|
injectIntoArg = "data",
|
|
4479
4479
|
sourceAttachmentId,
|
|
4480
|
-
threadId
|
|
4480
|
+
threadId,
|
|
4481
|
+
toolSchema
|
|
4481
4482
|
} = params;
|
|
4482
4483
|
const argsWithInjection = { ...enrichedArgs };
|
|
4483
4484
|
try {
|
|
4484
|
-
if (shouldInjectData(
|
|
4485
|
+
if (shouldInjectData(
|
|
4486
|
+
argsWithInjection,
|
|
4487
|
+
attachments,
|
|
4488
|
+
injectIntoArg,
|
|
4489
|
+
toolSchema
|
|
4490
|
+
)) {
|
|
4485
4491
|
const attachment = sourceAttachmentId ? attachments[sourceAttachmentId] : getLatestAttachment(attachments);
|
|
4486
4492
|
if (attachment) {
|
|
4487
4493
|
const attachmentKey = sourceAttachmentId || attachment.toolCallId;
|
|
@@ -4543,9 +4549,17 @@ async function executeToolWithAttachments(params) {
|
|
|
4543
4549
|
});
|
|
4544
4550
|
return { toolMessage };
|
|
4545
4551
|
}
|
|
4546
|
-
function shouldInjectData(args, attachments, dataArgName) {
|
|
4552
|
+
function shouldInjectData(args, attachments, dataArgName, toolSchema) {
|
|
4547
4553
|
if (Object.keys(attachments).length === 0) return false;
|
|
4548
|
-
|
|
4554
|
+
if (args[dataArgName] !== void 0) return false;
|
|
4555
|
+
if (toolSchema) {
|
|
4556
|
+
const hasProperty = toolSchema.properties && dataArgName in toolSchema.properties;
|
|
4557
|
+
const isRequired = toolSchema.required?.includes(dataArgName);
|
|
4558
|
+
if (!hasProperty && !isRequired) {
|
|
4559
|
+
return false;
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
return true;
|
|
4549
4563
|
}
|
|
4550
4564
|
var _internals = {
|
|
4551
4565
|
shouldInjectData,
|
|
@@ -6452,12 +6466,19 @@ function hashToolsConfig(toolsConfig) {
|
|
|
6452
6466
|
const sorted = toolsConfig.map((t) => `${t.toolName}:${t.enabled}:${JSON.stringify(t.config || {})}`).sort().join("|");
|
|
6453
6467
|
return crypto.createHash("md5").update(sorted).digest("hex").slice(0, 16);
|
|
6454
6468
|
}
|
|
6455
|
-
|
|
6469
|
+
var DEFAULT_ROUTER_URL = "https://router.flutch.ai";
|
|
6470
|
+
function resolveRouterURL(baseURL) {
|
|
6471
|
+
return baseURL ?? process.env.FLUTCH_ROUTER_URL ?? DEFAULT_ROUTER_URL;
|
|
6472
|
+
}
|
|
6473
|
+
function generateModelCacheKey(modelId, temperature, maxTokens, toolsConfig, baseURL) {
|
|
6456
6474
|
const parts = [
|
|
6457
6475
|
modelId,
|
|
6458
6476
|
temperature ?? "default",
|
|
6459
6477
|
maxTokens ?? "default"
|
|
6460
6478
|
];
|
|
6479
|
+
if (baseURL) {
|
|
6480
|
+
parts.push(baseURL);
|
|
6481
|
+
}
|
|
6461
6482
|
if (toolsConfig && toolsConfig.length > 0) {
|
|
6462
6483
|
parts.push(hashToolsConfig(toolsConfig));
|
|
6463
6484
|
}
|
|
@@ -6585,7 +6606,8 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
6585
6606
|
config.modelId,
|
|
6586
6607
|
config.temperature,
|
|
6587
6608
|
config.maxTokens,
|
|
6588
|
-
config.toolsConfig
|
|
6609
|
+
config.toolsConfig,
|
|
6610
|
+
config.baseURL
|
|
6589
6611
|
);
|
|
6590
6612
|
}
|
|
6591
6613
|
// Chat model creators
|
|
@@ -6594,7 +6616,8 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
6594
6616
|
modelName,
|
|
6595
6617
|
defaultTemperature,
|
|
6596
6618
|
defaultMaxTokens,
|
|
6597
|
-
apiToken
|
|
6619
|
+
apiToken,
|
|
6620
|
+
baseURL
|
|
6598
6621
|
}) => {
|
|
6599
6622
|
const config = buildOpenAIModelConfig(
|
|
6600
6623
|
modelName,
|
|
@@ -6602,18 +6625,21 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
6602
6625
|
defaultMaxTokens,
|
|
6603
6626
|
apiToken || this.resolveApiKey("openai" /* OPENAI */) || ""
|
|
6604
6627
|
);
|
|
6628
|
+
config.configuration = { baseURL: `${resolveRouterURL(baseURL)}/v1` };
|
|
6605
6629
|
return new openai.ChatOpenAI(config);
|
|
6606
6630
|
},
|
|
6607
6631
|
["anthropic" /* ANTHROPIC */]: ({
|
|
6608
6632
|
modelName,
|
|
6609
6633
|
defaultTemperature,
|
|
6610
6634
|
defaultMaxTokens,
|
|
6611
|
-
apiToken
|
|
6635
|
+
apiToken,
|
|
6636
|
+
baseURL
|
|
6612
6637
|
}) => new anthropic.ChatAnthropic({
|
|
6613
6638
|
modelName,
|
|
6614
6639
|
temperature: defaultTemperature,
|
|
6615
6640
|
maxTokens: defaultMaxTokens,
|
|
6616
|
-
anthropicApiKey: apiToken || this.resolveApiKey("anthropic" /* ANTHROPIC */)
|
|
6641
|
+
anthropicApiKey: apiToken || this.resolveApiKey("anthropic" /* ANTHROPIC */),
|
|
6642
|
+
anthropicApiUrl: resolveRouterURL(baseURL)
|
|
6617
6643
|
}),
|
|
6618
6644
|
["cohere" /* COHERE */]: ({
|
|
6619
6645
|
modelName,
|
|
@@ -6629,12 +6655,17 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
6629
6655
|
modelName,
|
|
6630
6656
|
defaultTemperature,
|
|
6631
6657
|
defaultMaxTokens,
|
|
6632
|
-
apiToken
|
|
6658
|
+
apiToken,
|
|
6659
|
+
baseURL
|
|
6633
6660
|
}) => new mistralai.ChatMistralAI({
|
|
6634
6661
|
model: modelName,
|
|
6635
6662
|
temperature: defaultTemperature,
|
|
6636
6663
|
maxTokens: defaultMaxTokens,
|
|
6637
|
-
apiKey: apiToken || this.resolveApiKey("mistral" /* MISTRAL */)
|
|
6664
|
+
apiKey: apiToken || this.resolveApiKey("mistral" /* MISTRAL */),
|
|
6665
|
+
// Route through the same gateway as OpenAI/Anthropic.
|
|
6666
|
+
// Without serverURL, ChatMistralAI ignores FLUTCH_ROUTER_URL and calls
|
|
6667
|
+
// api.mistral.ai directly — inconsistent with other providers.
|
|
6668
|
+
serverURL: `${resolveRouterURL(baseURL)}/v1`
|
|
6638
6669
|
}),
|
|
6639
6670
|
["voyageai" /* VOYAGEAI */]: () => {
|
|
6640
6671
|
throw new Error("VoyageAI chat models not implemented");
|
|
@@ -6695,7 +6726,8 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
6695
6726
|
),
|
|
6696
6727
|
defaultMaxTokens: Number(
|
|
6697
6728
|
config.maxTokens ?? modelConfig.defaultMaxTokens
|
|
6698
|
-
)
|
|
6729
|
+
),
|
|
6730
|
+
baseURL: config.baseURL ?? modelConfig.baseURL
|
|
6699
6731
|
};
|
|
6700
6732
|
this.logger.debug(`Creating new chat model instance: ${cacheKey}`);
|
|
6701
6733
|
let model;
|