@squidcloud/cli 1.0.489 → 1.0.490
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/index.js +120 -16
- package/dist/resources/claude/skills/squid-development/SKILL.md +2 -2
- package/dist/resources/claude/skills/squid-development/reference/ai.md +27 -3
- package/dist/resources/claude/skills/squid-development/reference/client.md +6 -1
- package/dist/resources/claude/skills/squid-development/reference/console.md +1 -0
- package/dist/resources/claude/skills/squid-integrations/SKILL.md +5 -3
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -32183,7 +32183,7 @@ __webpack_unused_export__ = isIntegrationModelSpec;
|
|
|
32183
32183
|
/**
|
|
32184
32184
|
* @category AI
|
|
32185
32185
|
*/
|
|
32186
|
-
__webpack_unused_export__ = ['cohere', 'none'];
|
|
32186
|
+
__webpack_unused_export__ = ['cohere', 'voyage', 'none'];
|
|
32187
32187
|
/** List of available AI provider types. See AiProviderType. */
|
|
32188
32188
|
exports.AI_PROVIDER_TYPES = [
|
|
32189
32189
|
'anthropic',
|
|
@@ -32245,6 +32245,7 @@ exports.Kq = ['grok-4.6', 'grok-4-1-fast-reasoning', 'grok-4-1-fast-non-reasonin
|
|
|
32245
32245
|
*/
|
|
32246
32246
|
exports.xV = [
|
|
32247
32247
|
'claude-fable-5',
|
|
32248
|
+
'claude-fable-5-1',
|
|
32248
32249
|
'claude-haiku-4-5-20251001',
|
|
32249
32250
|
'claude-opus-5',
|
|
32250
32251
|
'claude-sonnet-5',
|
|
@@ -32270,7 +32271,7 @@ exports.lZ = ['text-embedding-3-small'];
|
|
|
32270
32271
|
/**
|
|
32271
32272
|
* @category AI
|
|
32272
32273
|
*/
|
|
32273
|
-
exports.Pq = ['voyage-3-large'];
|
|
32274
|
+
exports.Pq = ['voyage-3-large', 'voyage-4-large', 'voyage-4'];
|
|
32274
32275
|
/**
|
|
32275
32276
|
* @category AI
|
|
32276
32277
|
*/
|
|
@@ -32392,6 +32393,7 @@ exports.CONNECTOR_IDS = [
|
|
|
32392
32393
|
'cotomi',
|
|
32393
32394
|
'essentials',
|
|
32394
32395
|
'freshdesk',
|
|
32396
|
+
'generic_site_ingester',
|
|
32395
32397
|
'github',
|
|
32396
32398
|
'google_calendar',
|
|
32397
32399
|
'google_drive',
|
|
@@ -32422,6 +32424,7 @@ var __webpack_unused_export__;
|
|
|
32422
32424
|
|
|
32423
32425
|
__webpack_unused_export__ = ({ value: true });
|
|
32424
32426
|
exports.EL = exports.y4 = exports.q7 = exports.lO = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = exports.INTEGRATION_TYPES = __webpack_unused_export__ = void 0;
|
|
32427
|
+
__webpack_unused_export__ = isIntegrationDisabled;
|
|
32425
32428
|
__webpack_unused_export__ = isBuiltInIntegrationId;
|
|
32426
32429
|
/** @internal */
|
|
32427
32430
|
__webpack_unused_export__ = 'ai_agents';
|
|
@@ -32459,11 +32462,13 @@ exports.INTEGRATION_TYPES = [
|
|
|
32459
32462
|
'descope',
|
|
32460
32463
|
'documentdb',
|
|
32461
32464
|
'azure-entra-external-id',
|
|
32465
|
+
'azure-entra-id',
|
|
32462
32466
|
'dynamodb',
|
|
32463
32467
|
'elasticsearch',
|
|
32464
32468
|
'firebase_auth',
|
|
32465
32469
|
'firestore',
|
|
32466
32470
|
'gcs',
|
|
32471
|
+
'generic_site_ingester',
|
|
32467
32472
|
'github',
|
|
32468
32473
|
'google_calendar',
|
|
32469
32474
|
'google_docs',
|
|
@@ -32544,6 +32549,7 @@ __webpack_unused_export__ = [
|
|
|
32544
32549
|
'descope',
|
|
32545
32550
|
'firebase_auth',
|
|
32546
32551
|
'azure-entra-external-id',
|
|
32552
|
+
'azure-entra-id',
|
|
32547
32553
|
];
|
|
32548
32554
|
/**
|
|
32549
32555
|
* Auth integration types that can OAuth-protect an MCP server (see `McpOAuthOptions` and
|
|
@@ -32570,6 +32576,10 @@ exports.q7 = 'built_in_queue';
|
|
|
32570
32576
|
* @category
|
|
32571
32577
|
*/
|
|
32572
32578
|
exports.y4 = 'built_in_storage';
|
|
32579
|
+
/** Returns true when the integration is explicitly disabled. An absent or null `enabled` means enabled. */
|
|
32580
|
+
function isIntegrationDisabled(integration) {
|
|
32581
|
+
return integration.enabled === false;
|
|
32582
|
+
}
|
|
32573
32583
|
/** Integration IDs used for built-in integrations by Squid. */
|
|
32574
32584
|
exports.EL = [
|
|
32575
32585
|
exports.lO,
|
|
@@ -33061,13 +33071,15 @@ exports.sQ = void 0;
|
|
|
33061
33071
|
__webpack_unused_export__ = isKotlinPath;
|
|
33062
33072
|
__webpack_unused_export__ = getEnvironmentPrefix;
|
|
33063
33073
|
exports.getApplicationUrl = getApplicationUrl;
|
|
33074
|
+
__webpack_unused_export__ = getQueryKotlinServiceUrl;
|
|
33064
33075
|
exports.sQ = [
|
|
33065
33076
|
'application',
|
|
33066
|
-
'auth',
|
|
33067
33077
|
'mutation',
|
|
33068
|
-
'native-query',
|
|
33069
33078
|
'query',
|
|
33070
33079
|
// Note: every `/ws/*` WebSocket path is served by the TypeScript core (port 8000), never Kotlin.
|
|
33080
|
+
// Note: `native-query` is absent on purpose — the TypeScript core answers it and forwards the
|
|
33081
|
+
// integration types it has no implementation for to Kotlin itself, via
|
|
33082
|
+
// {@link getQueryKotlinServiceUrl}.
|
|
33071
33083
|
];
|
|
33072
33084
|
/**
|
|
33073
33085
|
* Returns true if the given path is served by Kotlin core in local dev (port 8001). All `/ws/*`
|
|
@@ -33113,6 +33125,26 @@ function getApplicationUrl(environmentPrefix, appId, path, appIdPlaceholder, env
|
|
|
33113
33125
|
const cleanPath = path.replace(/^\/+/, '');
|
|
33114
33126
|
return cleanPath ? `${origin}/${cleanPath}` : origin;
|
|
33115
33127
|
}
|
|
33128
|
+
/**
|
|
33129
|
+
* Returns the URL of [path] on the `core-query-kotlin` Service, addressed from inside the cluster.
|
|
33130
|
+
*
|
|
33131
|
+
* Naming the Service rather than building the public URL with {@link getApplicationUrl} keeps a
|
|
33132
|
+
* purely intra-cluster call off the external load balancer, which is what the Kotlin core's own
|
|
33133
|
+
* `getApplicationUrlInternal` already does for the hop in the other direction; and it makes the call
|
|
33134
|
+
* independent of where ingress sends [path], so moving that route cannot turn a forward into a
|
|
33135
|
+
* request back to this core.
|
|
33136
|
+
*
|
|
33137
|
+
* The Service is shared and not per-app, so the application is identified by the
|
|
33138
|
+
* `SquidHeaders.APP_ID` header rather than by the hostname. Local development has no cluster DNS and
|
|
33139
|
+
* keeps the per-app host on Kotlin's port.
|
|
33140
|
+
*/
|
|
33141
|
+
function getQueryKotlinServiceUrl(environmentPrefix, appId, path) {
|
|
33142
|
+
if (isLocal(environmentPrefix)) {
|
|
33143
|
+
return getApplicationUrl(environmentPrefix, appId, path, undefined, undefined, true);
|
|
33144
|
+
}
|
|
33145
|
+
const cleanPath = path.replace(/^\/+/, '');
|
|
33146
|
+
return `http://core-query-kotlin.default.svc.cluster.local:8001/${cleanPath}`;
|
|
33147
|
+
}
|
|
33116
33148
|
function isLocal(regionPrefix) {
|
|
33117
33149
|
return /^local/.test(regionPrefix);
|
|
33118
33150
|
}
|
|
@@ -34467,6 +34499,20 @@ const SIGINT_STAGING_WAIT_MILLIS = 10 * time_units_1.MILLIS_PER_SECOND;
|
|
|
34467
34499
|
const DEFAULT_TIMEOUT_MINUTES = 120;
|
|
34468
34500
|
/** Interval between `bulk/getJob` polls while waiting for a job to reach a terminal state. */
|
|
34469
34501
|
const POLL_INTERVAL_MILLIS = 10 * time_units_1.MILLIS_PER_SECOND;
|
|
34502
|
+
/**
|
|
34503
|
+
* How old the last successful poll may be for the timeout classification to trust it. A status older
|
|
34504
|
+
* than this (every recent poll failed) says nothing about the job NOW, so the timeout falls back to the
|
|
34505
|
+
* conservative failure exit instead of waving a stale "still draining" snapshot through.
|
|
34506
|
+
*/
|
|
34507
|
+
const STALE_STATUS_TOLERANCE_MILLIS = 3 * POLL_INTERVAL_MILLIS;
|
|
34508
|
+
/**
|
|
34509
|
+
* How recently a poll must have observed an ACTIVE provider batch for a timeout to defer when NO work
|
|
34510
|
+
* is queued: the no-pending grace for the tick-long gap between one batch's reconciliation and the
|
|
34511
|
+
* next stage's submission. With `requestsPending > 0` behind an observed batch the deferral holds
|
|
34512
|
+
* regardless of this window (queued work is stalled-but-alive under cluster load); a job past this
|
|
34513
|
+
* window with nothing pending is wedged and takes the failure exit.
|
|
34514
|
+
*/
|
|
34515
|
+
const ACTIVE_BATCH_RECENCY_MILLIS = 5 * time_units_1.MILLIS_PER_MINUTE;
|
|
34470
34516
|
/** Extensions ingested by default when `--extensions` is not provided. */
|
|
34471
34517
|
const DEFAULT_EXTENSIONS = ['pdf', 'docx', 'txt', 'md', 'html', 'csv', 'xlsx', 'xls', 'xlsm', 'xlsb', 'pptx'];
|
|
34472
34518
|
/** Job states that end a bulk-ingestion job's lifecycle (`BulkIngestionJobState` in core). */
|
|
@@ -34477,6 +34523,7 @@ const UNKNOWN_JOB_STATUS = {
|
|
|
34477
34523
|
state: 'unknown',
|
|
34478
34524
|
counts: { files: 0, finalized: 0, failed: 0, requestsPending: 0, requestsSubmitted: 0 },
|
|
34479
34525
|
providerBatchIds: [],
|
|
34526
|
+
activeProviderBatchCount: 0,
|
|
34480
34527
|
files: [],
|
|
34481
34528
|
};
|
|
34482
34529
|
/**
|
|
@@ -34745,7 +34792,7 @@ onStagingStarted) {
|
|
|
34745
34792
|
console.log(`${batchLabel}: ${duplicates.length} file(s) skipped as content this knowledge base already holds.`);
|
|
34746
34793
|
}
|
|
34747
34794
|
activeJobIds.add(jobId);
|
|
34748
|
-
const { finalStatus, timedOut } = await waitForJobCompletion(client, jobId, batchLabel, timeoutMillis, isInterrupted);
|
|
34795
|
+
const { finalStatus, timedOut, statusStale, lastActiveBatchAtMillis } = await waitForJobCompletion(client, jobId, batchLabel, timeoutMillis, isInterrupted);
|
|
34749
34796
|
activeJobIds.delete(jobId);
|
|
34750
34797
|
// A duplicate found by the deferred extraction pass (a presigned object's bytes are first hashed
|
|
34751
34798
|
// there) reports as a failed file with `errorCode: 'DUPLICATE_CONTENT'` — the same skip a
|
|
@@ -34764,6 +34811,21 @@ onStagingStarted) {
|
|
|
34764
34811
|
duplicates: [...duplicates, ...deferredDuplicates],
|
|
34765
34812
|
finalStatus,
|
|
34766
34813
|
timedOut,
|
|
34814
|
+
// Only a FRESH status may waive the timeout, and only on OBSERVED batch activity: an active batch
|
|
34815
|
+
// on the final poll; one seen within the recency window; or one seen at ANY point of this wait
|
|
34816
|
+
// while queued work remains (`requestsPending > 0`) — inter-stage stalls scale with cluster load
|
|
34817
|
+
// (the submit pass visits ~20 running jobs per 15s tick, and an app at its in-flight batch cap
|
|
34818
|
+
// waits for a sibling to drain), so pending-work-behind-an-observed-batch is stalled-but-alive,
|
|
34819
|
+
// not wedged. A job with batches long drained and NOTHING pending takes the failure exit. The
|
|
34820
|
+
// job's `transport` is deliberately NOT consulted: it is 'batch' from staging for every large
|
|
34821
|
+
// job, batches or none, so it cannot say whether anything is draining NOW.
|
|
34822
|
+
deferredInFlight: timedOut &&
|
|
34823
|
+
!statusStale &&
|
|
34824
|
+
finalStatus.state === 'running' &&
|
|
34825
|
+
((finalStatus.activeProviderBatchCount ?? 0) > 0 ||
|
|
34826
|
+
(lastActiveBatchAtMillis > 0 &&
|
|
34827
|
+
(Date.now() - lastActiveBatchAtMillis < ACTIVE_BATCH_RECENCY_MILLIS ||
|
|
34828
|
+
finalStatus.counts.requestsPending > 0))),
|
|
34767
34829
|
};
|
|
34768
34830
|
}
|
|
34769
34831
|
/** Mints presigned upload URLs for a batch, chunking requests to the server's per-call cap. */
|
|
@@ -34822,7 +34884,10 @@ async function uploadFile(filePath, upload, stagedObjectKey) {
|
|
|
34822
34884
|
async function waitForJobCompletion(client, jobId, batchLabel, timeoutMillis, isInterrupted) {
|
|
34823
34885
|
const deadline = Date.now() + timeoutMillis;
|
|
34824
34886
|
let status;
|
|
34887
|
+
let statusAtMillis = 0;
|
|
34888
|
+
let lastActiveBatchAtMillis = 0;
|
|
34825
34889
|
let isFirstPoll = true;
|
|
34890
|
+
let deferralAnnounced = false;
|
|
34826
34891
|
while (!isInterrupted() && Date.now() < deadline && (!status || !TERMINAL_JOB_STATES.has(status.state))) {
|
|
34827
34892
|
if (!isFirstPoll) {
|
|
34828
34893
|
await sleep(POLL_INTERVAL_MILLIS);
|
|
@@ -34830,6 +34895,17 @@ async function waitForJobCompletion(client, jobId, batchLabel, timeoutMillis, is
|
|
|
34830
34895
|
isFirstPoll = false;
|
|
34831
34896
|
try {
|
|
34832
34897
|
status = await client.getJob(jobId);
|
|
34898
|
+
statusAtMillis = Date.now();
|
|
34899
|
+
if ((status.activeProviderBatchCount ?? 0) > 0) {
|
|
34900
|
+
lastActiveBatchAtMillis = statusAtMillis;
|
|
34901
|
+
if (!deferralAnnounced) {
|
|
34902
|
+
deferralAnnounced = true;
|
|
34903
|
+
console.log(`\n${batchLabel}: job ${jobId} submitted a provider batch — half-price processing whose tail can ` +
|
|
34904
|
+
`reach 24 hours, possibly past --timeoutMinutes. A timed-out wait leaves the job running ` +
|
|
34905
|
+
`without failing the run; the job finishes server-side, and re-runs are idempotent ` +
|
|
34906
|
+
`(already-staged content skips as duplicate).`);
|
|
34907
|
+
}
|
|
34908
|
+
}
|
|
34833
34909
|
printProgress(batchLabel, jobId, status);
|
|
34834
34910
|
}
|
|
34835
34911
|
catch (error) {
|
|
@@ -34839,13 +34915,18 @@ async function waitForJobCompletion(client, jobId, batchLabel, timeoutMillis, is
|
|
|
34839
34915
|
process.stdout.write('\n');
|
|
34840
34916
|
if (!status) {
|
|
34841
34917
|
console.warn(`${batchLabel}: could not retrieve job ${jobId}'s status before the timeout.`);
|
|
34842
|
-
return { finalStatus: UNKNOWN_JOB_STATUS, timedOut: true };
|
|
34918
|
+
return { finalStatus: UNKNOWN_JOB_STATUS, timedOut: true, statusStale: true, lastActiveBatchAtMillis: 0 };
|
|
34843
34919
|
}
|
|
34844
34920
|
const timedOut = !TERMINAL_JOB_STATES.has(status.state) && !isInterrupted();
|
|
34845
34921
|
if (timedOut) {
|
|
34846
34922
|
console.warn(`${batchLabel}: job ${jobId} did not finish within the timeout; it may still be running server-side.`);
|
|
34847
34923
|
}
|
|
34848
|
-
return {
|
|
34924
|
+
return {
|
|
34925
|
+
finalStatus: status,
|
|
34926
|
+
timedOut,
|
|
34927
|
+
statusStale: Date.now() - statusAtMillis > STALE_STATUS_TOLERANCE_MILLIS,
|
|
34928
|
+
lastActiveBatchAtMillis,
|
|
34929
|
+
};
|
|
34849
34930
|
}
|
|
34850
34931
|
/** Best-effort cancellation of every job still active when the process is interrupted. */
|
|
34851
34932
|
async function cancelActiveJobs(client, activeJobIds) {
|
|
@@ -34913,6 +34994,17 @@ function printSummary(totalFiles, results) {
|
|
|
34913
34994
|
if (totalStagedButFailed > 0) {
|
|
34914
34995
|
console.log(`Staged but job failed: ${totalStagedButFailed} (uploaded objects remain; auto-expire in 24h)`);
|
|
34915
34996
|
}
|
|
34997
|
+
const totalStillDeferred = results.reduce((sum, result) => result.deferredInFlight
|
|
34998
|
+
? sum +
|
|
34999
|
+
Math.max(0, (result.finalStatus?.counts.files ?? 0) -
|
|
35000
|
+
(result.finalStatus?.counts.finalized ?? 0) -
|
|
35001
|
+
(result.finalStatus?.counts.failed ?? 0))
|
|
35002
|
+
: sum, 0);
|
|
35003
|
+
if (totalStillDeferred > 0) {
|
|
35004
|
+
// Reconciles the summary the same way the duplicates line does: these files are neither finalized
|
|
35005
|
+
// nor failed, and without this line they read as silently missing from a run that exits 0.
|
|
35006
|
+
console.log(`Still processing: ${totalStillDeferred} (queued or draining server-side; the job finishes there)`);
|
|
35007
|
+
}
|
|
34916
35008
|
for (const result of results) {
|
|
34917
35009
|
const label = `batch ${result.batchIndex + 1}/${result.batchCount}`;
|
|
34918
35010
|
if (result.stagingError) {
|
|
@@ -34928,9 +35020,11 @@ function printSummary(totalFiles, results) {
|
|
|
34928
35020
|
console.log(` ${label}: no job created (all uploads failed)`);
|
|
34929
35021
|
continue;
|
|
34930
35022
|
}
|
|
34931
|
-
const state = result.
|
|
34932
|
-
?
|
|
34933
|
-
: result.
|
|
35023
|
+
const state = result.deferredInFlight
|
|
35024
|
+
? 'running — work still queued or draining server-side (batch tail can reach 24h); re-runs are idempotent'
|
|
35025
|
+
: result.timedOut
|
|
35026
|
+
? `${result.finalStatus?.state ?? 'unknown'} (timed out waiting)`
|
|
35027
|
+
: result.finalStatus?.state;
|
|
34934
35028
|
// Deferred duplicates are excluded from BOTH the failed count and the per-file failure lines: they
|
|
34935
35029
|
// are already named on the "skipped" lines below, and a clean idempotent re-run must not read as
|
|
34936
35030
|
// "0/1 finalized, 1 failed" while exiting 0 — the CLI tells one story about a skip.
|
|
@@ -34951,14 +35045,21 @@ function printSummary(totalFiles, results) {
|
|
|
34951
35045
|
}
|
|
34952
35046
|
}
|
|
34953
35047
|
function hasBatchFailed(result) {
|
|
34954
|
-
if (result.uploadFailures.length > 0
|
|
35048
|
+
if (result.uploadFailures.length > 0)
|
|
34955
35049
|
return true;
|
|
34956
35050
|
if (!result.finalStatus)
|
|
34957
35051
|
return true;
|
|
34958
35052
|
// Deferred duplicates are skips, not failures: an idempotent re-run over an already-ingested
|
|
34959
35053
|
// directory must exit 0, exactly as it does when staging rejects the duplicates synchronously.
|
|
34960
35054
|
const duplicateFailures = result.finalStatus.files.filter(file => file.errorCode === 'DUPLICATE_CONTENT').length;
|
|
34961
|
-
|
|
35055
|
+
const nonDuplicateFailed = result.finalStatus.counts.failed - duplicateFailures;
|
|
35056
|
+
// A wait-budget expiry on a still-draining provider batch is not a failure BY ITSELF: the pending
|
|
35057
|
+
// files will finish server-side, and exiting 1 would report success-in-progress as an error to every
|
|
35058
|
+
// unattended corpus load. Files the job has ALREADY failed still fail the run — a deferral must never
|
|
35059
|
+
// hide them behind exit 0. Every other timeout shape fails the run outright.
|
|
35060
|
+
if (result.timedOut)
|
|
35061
|
+
return result.deferredInFlight ? nonDuplicateFailed > 0 : true;
|
|
35062
|
+
return result.finalStatus.state !== 'completed' || nonDuplicateFailed > 0;
|
|
34962
35063
|
}
|
|
34963
35064
|
/** Recursively walks `dir`, skipping symlinks and dotfiles/dot-directories, filtered to `extensions`. */
|
|
34964
35065
|
async function collectFiles(dir, extensions) {
|
|
@@ -35554,6 +35655,9 @@ const process_utils_1 = __webpack_require__(8251);
|
|
|
35554
35655
|
const report_utils_1 = __webpack_require__(3066);
|
|
35555
35656
|
const version_check_1 = __webpack_require__(4827);
|
|
35556
35657
|
const ORG = 'squid-cloud-samples';
|
|
35658
|
+
// Audit and fund are extra registry round-trips that tell the user nothing about a project the
|
|
35659
|
+
// CLI just generated, and the audit request alone can take minutes.
|
|
35660
|
+
const NPM_INSTALL_COMMAND = 'npm install --no-audit --no-fund';
|
|
35557
35661
|
async function initSample(consoleRegion, isOnPremConsole, dirPath, appId, apiKey, environmentId, squidDeveloperId, region, templateName, verbose = false) {
|
|
35558
35662
|
(0, global_utils_1.enableDebugLogs)(verbose || (0, global_utils_1.isDebugEnabled)());
|
|
35559
35663
|
(0, logpipes_1.installConsoleOverrides)(enable_debug_decorator_utils_1.debugLogFilterPipe);
|
|
@@ -35602,18 +35706,18 @@ async function initSample(consoleRegion, isOnPremConsole, dirPath, appId, apiKey
|
|
|
35602
35706
|
let monorepo = false;
|
|
35603
35707
|
try {
|
|
35604
35708
|
await promises_1.default.access(path_1.default.resolve(dirPath, 'package.json'));
|
|
35605
|
-
await (0, shell_runner_1.runInShell)(
|
|
35709
|
+
await (0, shell_runner_1.runInShell)(NPM_INSTALL_COMMAND, verbose, path_1.default.resolve(dirPath));
|
|
35606
35710
|
}
|
|
35607
35711
|
catch { }
|
|
35608
35712
|
try {
|
|
35609
35713
|
await promises_1.default.access(path_1.default.resolve(dirPath, 'backend'));
|
|
35610
|
-
await (0, shell_runner_1.runInShell)(
|
|
35714
|
+
await (0, shell_runner_1.runInShell)(NPM_INSTALL_COMMAND, verbose, path_1.default.resolve(dirPath, 'backend'));
|
|
35611
35715
|
monorepo = true;
|
|
35612
35716
|
}
|
|
35613
35717
|
catch { }
|
|
35614
35718
|
try {
|
|
35615
35719
|
await promises_1.default.access(path_1.default.resolve(dirPath, 'frontend'));
|
|
35616
|
-
await (0, shell_runner_1.runInShell)(
|
|
35720
|
+
await (0, shell_runner_1.runInShell)(NPM_INSTALL_COMMAND, verbose, path_1.default.resolve(dirPath, 'frontend'));
|
|
35617
35721
|
}
|
|
35618
35722
|
catch { }
|
|
35619
35723
|
const hasEnvars = appId && region && apiKey && environmentId && squidDeveloperId;
|
|
@@ -40779,7 +40883,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"name":"seek-bzip","version":"1.0.6",
|
|
|
40779
40883
|
(module) {
|
|
40780
40884
|
|
|
40781
40885
|
"use strict";
|
|
40782
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@squidcloud/cli","version":"1.0.
|
|
40886
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@squidcloud/cli","version":"1.0.490","description":"The Squid CLI","main":"dist/index.js","scripts":{"start":"node dist/index.js","start-ts":"ts-node -r tsconfig-paths/register src/index.ts","prebuild":"rimraf dist","build":"webpack --mode=production","build:dev":"webpack --mode=development","lint":"eslint","link":"npm run build && chmod 755 dist/index.js && npm link","watch":"webpack --watch","deploy":"npm run build && npm pack --silent | xargs -I {} mv {} package.tgz && npm install -g package.tgz && rm -rf package.tgz","publish:public":"npm run build && npm publish --access public"},"files":["dist/**/*"],"bin":{"squid":"dist/index.js"},"keywords":[],"author":"","license":"ISC","engines":{"node":">=18.0.0"},"dependencies":{"@squidcloud/local-backend":"^1.0.490","adm-zip":"^0.5.16","copy-webpack-plugin":"^14.0.0","decompress":"^4.2.1","logpipes":"^1.11.0","nodemon":"^3.1.9","terser-webpack-plugin":"^5.5.0","ts-loader":"^9.5.1","ts-node":"^10.9.2","tsconfig-paths":"^4.2.0","tsconfig-paths-webpack-plugin":"^4.1.0","webpack":"^5.106.2","zip-webpack-plugin":"^4.0.1"},"devDependencies":{"@types/adm-zip":"^0.5.7","@types/decompress":"^4.2.7","terminal-link":"^3.0.0"}}');
|
|
40783
40887
|
|
|
40784
40888
|
/***/ }
|
|
40785
40889
|
|
|
@@ -22,8 +22,8 @@ Squid is a backend-as-a-service platform that provides:
|
|
|
22
22
|
## Feature-Specific Guidance
|
|
23
23
|
|
|
24
24
|
- **[client.md](reference/client.md)** → client SDK, initialization, setup, auth, login, tokens, OAuth, appId, region, environmentId, apiKey, authProvider, getToken, setAuthProvider, Squid client, frontend, collection, executeFunction, executeFunctionWithHeaders, getWebhookUrl, externalAuth, saveAuthCode, getAccessToken, storage, uploadFile, downloadUrl, queues, produce, consume, distributed locks, acquireLock, withLock, web, aiSearch, allowedDomains, getUrlContent, createShortUrl, jobs, getJob, awaitJob, startJob, completeJob, failJob, events, squid.events(), emit, TriggerEvent, LangGraph, squid.langGraph(), invoke, invokeAsync, resume, getState, deleteThread, observability, metrics, reportMetric, queryMetrics, setMetricAnnotations, notifications, publishNotification, observeNotifications
|
|
25
|
-
- **[console.md](reference/console.md)** → Squid Console, web UI, organizations, applications, AI Studio, knowledge bases, knowledge graph toggle, integrations, monitoring, logs, API keys, secrets, testing, debugging, profile settings, management API keys
|
|
26
|
-
- **[ai.md](reference/ai.md)** → AI agents, chat, ask, askWithAnnotations, askAsync, askWithVoiceResponse, transcribeAndChat, transcribeAndAsk, knowledge bases, RAG, embeddings, image generation, audio, transcription, text-to-speech, TTS, connectedAgents, connectedIntegrations, connectedKnowledgeBases, @aiFunction, @secureAiAgent, @secureAiQuery, memory, memoryOptions, metricAnnotations, voiceOptions, OpenAI, Anthropic, Gemini, Grok, DALL-E, Whisper, MCP, @mcpServer, @mcpTool, agent as MCP server, updateMcpServer, generateMcpDescriptions, agent API key, executeAiQuery, executeAiApiCall, extraction, createPdf, upsert agent, listAgents, listChatModels, listFunctions, spreadsheet understanding, querySpreadsheetsWithAi, searchMode, keyword search, xlsx, csv, grep, literal scan, knowledge graph, GraphRAG, graphRag, graph search, queryGraph, getGraphStatus, rebuildGraph, exploreGraph, searchWithGraphContext, graphOptions, graphFilter, underConcept, entityTypes, queryKnowledgeGraph, bulk ingestion, bulkUpsertContexts, createBulkUploadUrls, observeBulkIngestionJob, listContextsPage, generateMetadataFieldDescriptions
|
|
25
|
+
- **[console.md](reference/console.md)** → Squid Console, web UI, organizations, applications, AI Studio, knowledge bases, knowledge graph toggle, extraction method dropdown, integrations, monitoring, logs, API keys, secrets, testing, debugging, profile settings, management API keys
|
|
26
|
+
- **[ai.md](reference/ai.md)** → AI agents, chat, ask, askWithAnnotations, askAsync, askWithVoiceResponse, transcribeAndChat, transcribeAndAsk, knowledge bases, RAG, embeddings, image generation, audio, transcription, text-to-speech, TTS, connectedAgents, connectedIntegrations, connectedKnowledgeBases, @aiFunction, @secureAiAgent, @secureAiQuery, memory, memoryOptions, metricAnnotations, voiceOptions, OpenAI, Anthropic, Gemini, Grok, DALL-E, Whisper, MCP, @mcpServer, @mcpTool, agent as MCP server, updateMcpServer, generateMcpDescriptions, agent API key, executeAiQuery, executeAiApiCall, extraction, createPdf, upsert agent, listAgents, listChatModels, listFunctions, spreadsheet understanding, querySpreadsheetsWithAi, searchMode, keyword search, xlsx, csv, grep, literal scan, knowledge graph, GraphRAG, graphRag, graph search, queryGraph, getGraphStatus, rebuildGraph, exploreGraph, searchWithGraphContext, graphOptions, graphFilter, underConcept, entityTypes, queryKnowledgeGraph, bulk ingestion, bulkUpsertContexts, createBulkUploadUrls, observeBulkIngestionJob, listContextsPage, generateMetadataFieldDescriptions, extraction method, preferredExtractionMethod, legacy_with_llm, mistral_ocr, amazon_textract, azure_document_intelligence, page screenshot, image description, extractImages
|
|
27
27
|
- **[chat-widget.md](reference/chat-widget.md)** → AI chat widget, @squidcloud/react-chat-widget, squid-chat-widget, squid-chat-widget-with-fab-button, embeddable chat, custom API webhook, AI query mode, chain-of-thought, status updates, session management, agentContext, memoryOptions, squid-ai-custom-api-url, squid-ai-agent-chat-options, FAB button, theming, CSS variables, localization, RTL, menu items slots, suggested prompts, voice transcription, error formatting, authentication, squid-auth-provider, onChange events
|
|
28
28
|
- **[databases.md](reference/databases.md)** → collections, documents, queries, subscriptions, snapshots, insert, update, delete, CRUD, real-time, dereference, pagination, transactions, query operators, eq, neq, gt, gte, lt, lte, like, in, nin, arrayIncludesSome, arrayIncludesAll, sortBy, limit, join queries, OR queries, @trigger, native queries, SQL, MongoDB, Elasticsearch, incrementInPath, decrementInPath, watch changes, doc(), docId, docIds, query.delete(), delete by query, projectFields, field projection, __docId__, __id
|
|
29
29
|
- **[backend.md](reference/backend.md)** → SquidService, @executable, @webhook, @trigger, TriggerRequest, @scheduler, @limits, rate limiting, quotas, decorators, backend functions, WebhookRequest, CronExpression, cron, file handling, SquidFile, getUserAuth, isAuthenticated, assertIsAuthenticated, createWebhookResponse, this.squid, getSquid, getPassiveSquid, this.secrets, @clientConnectionStateHandler, @onQueueMessage, QueueMessageRequest, queue message handler, server-side queue consumer, @eventHandler, event handler, workspace, CLI, squid init, squid start, squid deploy, squid build, squid kb-upload, printBundle, project structure, multiple services, service architecture, squidInject, cross-service communication
|
|
@@ -128,7 +128,7 @@ console.log(agentInfo.id, agentInfo.description, agentInfo.options.model);
|
|
|
128
128
|
// Update specific properties
|
|
129
129
|
await myAgent.updateInstructions('You are a technical support specialist.');
|
|
130
130
|
await myAgent.updateModel('claude-sonnet-5');
|
|
131
|
-
await myAgent.updateGuardrails(
|
|
131
|
+
await myAgent.updateGuardrails({ disableProfanity: true, disablePii: true });
|
|
132
132
|
|
|
133
133
|
// Delete an agent
|
|
134
134
|
await myAgent.delete();
|
|
@@ -393,7 +393,11 @@ const chatObs = agent.chat('What is your return policy?', {
|
|
|
393
393
|
instructions: 'Additional instructions for this request only',
|
|
394
394
|
responseFormat: 'json_object', // or 'text'
|
|
395
395
|
verbosity: 'medium', // 'low' | 'medium' | 'high' (OpenAI only)
|
|
396
|
-
reasoningEffort: 'high', // 'minimal' | 'low' | 'medium' | 'high'
|
|
396
|
+
reasoningEffort: 'high', // 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'ultra'
|
|
397
|
+
// (for reasoning models). On an `openai_compatible` integration the value
|
|
398
|
+
// is sent to the endpoint as written, so a level outside this list reaches
|
|
399
|
+
// it too — OpenAI's Chat Completions API, for one, serves function tools on
|
|
400
|
+
// a gpt-5.6 model only with reasoning off outright (`'none'`).
|
|
397
401
|
|
|
398
402
|
// Context & RAG
|
|
399
403
|
disableContext: false,
|
|
@@ -404,7 +408,13 @@ const chatObs = agent.chat('What is your return policy?', {
|
|
|
404
408
|
},
|
|
405
409
|
|
|
406
410
|
// Guardrails & quotas
|
|
407
|
-
guardrails:
|
|
411
|
+
guardrails: {
|
|
412
|
+
disableProfanity: true,
|
|
413
|
+
offTopicAnswers: true,
|
|
414
|
+
professionalTone: true,
|
|
415
|
+
disablePii: true,
|
|
416
|
+
custom: 'Never reveal internal case numbers'
|
|
417
|
+
},
|
|
408
418
|
quotas: {
|
|
409
419
|
maxAiCallStackSize: 5
|
|
410
420
|
},
|
|
@@ -530,6 +540,12 @@ await kb.upsertContexts([
|
|
|
530
540
|
{ contextId: 'doc-2', text: '...' }
|
|
531
541
|
], optionalFiles);
|
|
532
542
|
|
|
543
|
+
// File contexts can pick how the document is extracted — see "Document Extraction Methods" below
|
|
544
|
+
await kb.upsertContexts(
|
|
545
|
+
[{ contextId: 'report-1', type: 'file', preferredExtractionMethod: 'legacy_with_llm' }],
|
|
546
|
+
[reportPdfFile]
|
|
547
|
+
);
|
|
548
|
+
|
|
533
549
|
// Search with prompt
|
|
534
550
|
const results = await kb.searchContextsWithPrompt({
|
|
535
551
|
prompt: 'How do I reset password?',
|
|
@@ -784,6 +800,14 @@ await kb.bulkUpsertContexts(uploads.map(u => ({ type: 'file', stagedObjectKey: u
|
|
|
784
800
|
The CLI wraps this whole flow: `squid kb-upload --dir ./docs --knowledgeBase my-kb` (see
|
|
785
801
|
[backend.md](backend.md#cli-commands)).
|
|
786
802
|
|
|
803
|
+
### Document Extraction Methods
|
|
804
|
+
|
|
805
|
+
File contexts (and `squid.extraction()` calls) accept `preferredExtractionMethod: 'mistral_ocr' | 'legacy' | 'legacy_with_llm' | 'amazon_textract' | 'azure_document_intelligence'`. Default: the deployment's `defaultDocExtractionMethod` (usually `mistral_ocr`). The OCR providers (`mistral_ocr`, `amazon_textract`, `azure_document_intelligence`) are available only where the deployment configures them; `legacy` and `legacy_with_llm` run in-process and are always available. The same option applies to `upsertContexts`, `bulkUpsertContexts`, and the extraction client alike.
|
|
806
|
+
|
|
807
|
+
- `legacy` — reads the PDF's text layer (pdfjs) and extracts embedded images; no external service, but a scanned page yields nothing (there is no text layer to read). Console label: **Basic**.
|
|
808
|
+
- `legacy_with_llm` — the same text extraction, plus a screenshot of each page described by a vision model as a *complement* to the stored page text: figures, charts, layout, handwriting, and scanned regions the text layer cannot carry, without restating the page's prose. Notably, vector-drawn figures/graphs are not embedded images, so `legacy` cannot see them at all; the page screenshot (like provider OCR) is what catches them. Each description lands as its own chunk beside the page's text chunk, with page provenance; a page whose screenshot adds nothing beyond its text stores no extra chunk. Costs one vision call per page, so ingestion of long documents is slower and pricier than `legacy`. Console label: **Basic + page understanding**.
|
|
809
|
+
- `extractImages` (default `true` for file contexts) gates image handling for every method, including the `legacy_with_llm` page screenshots; `imageMinSizePixels` (default 100) filters small embedded images; `imageExtractionModel` overrides the model used for image/screenshot descriptions.
|
|
810
|
+
|
|
787
811
|
### Spreadsheet Understanding
|
|
788
812
|
|
|
789
813
|
Spreadsheet files (`.csv`, `.tsv`, `.xlsx`, `.xlsm`, `.xls`, `.xlsb`) uploaded as file context take a dedicated ingestion lane: instead of chunking raw cell text, Squid extracts the workbook structure (sheets, headers, hidden sheets; charts and pivot tables where the format exposes them — absent for CSV/TSV and `.xls`, pivots also absent for `.xlsb`) and embeds a generated whole-workbook summary, so search results describe what a workbook contains.
|
|
@@ -389,7 +389,12 @@ const extractedData = await extraction.extractDataFromDocumentFile(
|
|
|
389
389
|
{ name: 'total', type: 'number', description: 'Total amount' },
|
|
390
390
|
{ name: 'date', type: 'date', description: 'Invoice date' }
|
|
391
391
|
]
|
|
392
|
-
}
|
|
392
|
+
},
|
|
393
|
+
// 'mistral_ocr' | 'legacy' | 'legacy_with_llm' | 'amazon_textract' | 'azure_document_intelligence'.
|
|
394
|
+
// Default: the deployment's configured method (usually 'mistral_ocr'). Semantics: see the
|
|
395
|
+
// "Document Extraction Methods" section in ai.md.
|
|
396
|
+
preferredExtractionMethod: 'legacy_with_llm',
|
|
397
|
+
extractImages: true // default true; also gates legacy_with_llm's page screenshots
|
|
393
398
|
}
|
|
394
399
|
);
|
|
395
400
|
|
|
@@ -73,6 +73,7 @@ The AI Studio provides visual tools for building and testing AI agents:
|
|
|
73
73
|
|
|
74
74
|
### Managing Content
|
|
75
75
|
- Upload documents (PDF, text, markdown, etc.)
|
|
76
|
+
- Pick the **Extraction Method** in the add-knowledge dialog: **Basic** (`legacy`, in-process text extraction) and **Basic + page understanding** (`legacy_with_llm`, adds an LLM description of each page's screenshot) are always offered; OCR providers (**Mistral OCR**, **Amazon Textract**, **Azure AI Document Intelligence**) appear when the deployment configures them, with the deployment default marked **(Default)**
|
|
76
77
|
- View and edit contexts
|
|
77
78
|
- Search and preview indexed content
|
|
78
79
|
- Monitor indexing status
|
|
@@ -194,9 +194,11 @@ const content = await squid.web().getUrlContent('https://example.com');
|
|
|
194
194
|
// Short URLs
|
|
195
195
|
const shortUrl = await squid.web().createShortUrl('https://long-url.com/path');
|
|
196
196
|
|
|
197
|
-
// Data Extraction from documents
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
// Data Extraction from documents. Optional preferredExtractionMethod:
|
|
198
|
+
// 'mistral_ocr' | 'legacy' | 'legacy_with_llm' | 'amazon_textract' | 'azure_document_intelligence'
|
|
199
|
+
// (see the squid-development skill's ai.md "Document Extraction Methods")
|
|
200
|
+
const data = await squid.extraction().extractDataFromDocumentUrl(url);
|
|
201
|
+
const data = await squid.extraction().extractDataFromDocumentFile(file, { preferredExtractionMethod: 'legacy_with_llm' });
|
|
200
202
|
|
|
201
203
|
// PDF Creation
|
|
202
204
|
const pdf = await squid.extraction().createPdf(htmlContent);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squidcloud/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.490",
|
|
4
4
|
"description": "The Squid CLI",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node": ">=18.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@squidcloud/local-backend": "^1.0.
|
|
31
|
+
"@squidcloud/local-backend": "^1.0.490",
|
|
32
32
|
"adm-zip": "^0.5.16",
|
|
33
33
|
"copy-webpack-plugin": "^14.0.0",
|
|
34
34
|
"decompress": "^4.2.1",
|