@theokit/agents 6.4.2 → 7.0.0
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/LICENSE +201 -0
- package/dist/auth.js +1 -1
- package/dist/auth.js.map +1 -1
- package/dist/{bridge-entry-B-DQXIgk.d.ts → bridge-entry-F9XyPi0K.d.ts} +70 -10
- package/dist/bridge.d.ts +1 -1
- package/dist/bridge.js +2 -2
- package/dist/bridge.js.map +1 -1
- package/dist/{chunk-UJPG3K26.js → chunk-3YPKTOJ6.js} +526 -392
- package/dist/chunk-3YPKTOJ6.js.map +1 -0
- package/dist/{chunk-NTDOKNSU.js → chunk-FCGL2PEC.js} +2 -2
- package/dist/chunk-FCGL2PEC.js.map +1 -0
- package/dist/{chunk-7QVYU63E.js → chunk-Z4QWC7IK.js} +1 -1
- package/dist/chunk-Z4QWC7IK.js.map +1 -0
- package/dist/client-react.js +2 -2
- package/dist/client-react.js.map +1 -1
- package/dist/client.js +2 -2
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/interactive.js +1 -1
- package/dist/interactive.js.map +1 -1
- package/dist/persistence.d.ts +1 -1
- package/dist/persistence.js +3 -3
- package/dist/persistence.js.map +1 -1
- package/dist/pty.js +1 -1
- package/dist/pty.js.map +1 -1
- package/dist/sandbox.d.ts +1 -1
- package/dist/sandbox.js +3 -3
- package/dist/sandbox.js.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/tools.js +1 -1
- package/dist/tools.js.map +1 -1
- package/package.json +12 -12
- package/dist/chunk-7QVYU63E.js.map +0 -1
- package/dist/chunk-NTDOKNSU.js.map +0 -1
- package/dist/chunk-UJPG3K26.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__name
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Z4QWC7IK.js";
|
|
4
4
|
|
|
5
5
|
// src/errors.ts
|
|
6
6
|
import { ConfigurationError } from "@theokit/sdk/errors";
|
|
@@ -455,6 +455,198 @@ function generateAgentRoutes(ctx) {
|
|
|
455
455
|
}
|
|
456
456
|
__name(generateAgentRoutes, "generateAgentRoutes");
|
|
457
457
|
|
|
458
|
+
// src/guardrails/types.ts
|
|
459
|
+
var GuardrailViolationError = class extends Error {
|
|
460
|
+
static {
|
|
461
|
+
__name(this, "GuardrailViolationError");
|
|
462
|
+
}
|
|
463
|
+
guardName;
|
|
464
|
+
phase;
|
|
465
|
+
reason;
|
|
466
|
+
constructor(guardName, phase, reason) {
|
|
467
|
+
super(`Guardrail "${guardName}" blocked ${phase}: ${reason}`), this.guardName = guardName, this.phase = phase, this.reason = reason;
|
|
468
|
+
this.name = "GuardrailViolationError";
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
var CostBudgetExceededError = class extends Error {
|
|
472
|
+
static {
|
|
473
|
+
__name(this, "CostBudgetExceededError");
|
|
474
|
+
}
|
|
475
|
+
usedTokens;
|
|
476
|
+
maxTokens;
|
|
477
|
+
constructor(usedTokens, maxTokens) {
|
|
478
|
+
super(`Cost budget exceeded: ${usedTokens} > ${maxTokens} tokens`), this.usedTokens = usedTokens, this.maxTokens = maxTokens;
|
|
479
|
+
this.name = "CostBudgetExceededError";
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// src/guardrails/detectors.ts
|
|
484
|
+
function estimateTokens(text) {
|
|
485
|
+
return Math.ceil(text.length / 4);
|
|
486
|
+
}
|
|
487
|
+
__name(estimateTokens, "estimateTokens");
|
|
488
|
+
var INJECTION_PHRASES = [
|
|
489
|
+
"previous instructions",
|
|
490
|
+
"disregard the above",
|
|
491
|
+
"you are now dan",
|
|
492
|
+
"system prompt",
|
|
493
|
+
"no restrictions",
|
|
494
|
+
"without restrictions",
|
|
495
|
+
"no rules",
|
|
496
|
+
"override your"
|
|
497
|
+
];
|
|
498
|
+
function normalizeForMatch(text) {
|
|
499
|
+
return text.toLowerCase().replace(/\s+/g, " ");
|
|
500
|
+
}
|
|
501
|
+
__name(normalizeForMatch, "normalizeForMatch");
|
|
502
|
+
function promptInjectionDetector(options = {}) {
|
|
503
|
+
const phrases = [
|
|
504
|
+
...INJECTION_PHRASES,
|
|
505
|
+
...(options.extra ?? []).map((p) => p.toLowerCase())
|
|
506
|
+
];
|
|
507
|
+
return {
|
|
508
|
+
name: "prompt-injection",
|
|
509
|
+
checkInput(text) {
|
|
510
|
+
const normalized = normalizeForMatch(text);
|
|
511
|
+
for (const phrase of phrases) {
|
|
512
|
+
if (normalized.includes(phrase)) {
|
|
513
|
+
return {
|
|
514
|
+
action: "block",
|
|
515
|
+
reason: `prompt injection phrase matched: "${phrase}"`
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return {
|
|
520
|
+
action: "allow"
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
__name(promptInjectionDetector, "promptInjectionDetector");
|
|
526
|
+
var CPF = /\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b/g;
|
|
527
|
+
var EMAIL = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g;
|
|
528
|
+
var PHONE = /\+?\d[\d\s()-]{7,13}\d/g;
|
|
529
|
+
function piiDetector(options = {}) {
|
|
530
|
+
const placeholder = options.placeholder ?? "[REDACTED]";
|
|
531
|
+
return {
|
|
532
|
+
name: "pii",
|
|
533
|
+
checkInput(text) {
|
|
534
|
+
let redacted = text;
|
|
535
|
+
redacted = redacted.replace(EMAIL, placeholder);
|
|
536
|
+
redacted = redacted.replace(CPF, placeholder);
|
|
537
|
+
redacted = redacted.replace(PHONE, placeholder);
|
|
538
|
+
if (redacted === text) return {
|
|
539
|
+
action: "allow"
|
|
540
|
+
};
|
|
541
|
+
return {
|
|
542
|
+
action: "redact",
|
|
543
|
+
text: redacted,
|
|
544
|
+
reason: "PII detected and redacted"
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
__name(piiDetector, "piiDetector");
|
|
550
|
+
var OBFUSCATION_CHARS = /[\u200B-\u200D\uFEFF\u202A-\u202E\u2066-\u2069]/g;
|
|
551
|
+
function unicodeNormalizer() {
|
|
552
|
+
return {
|
|
553
|
+
name: "unicode-normalizer",
|
|
554
|
+
checkInput(text) {
|
|
555
|
+
const cleaned = text.normalize("NFKC").replace(OBFUSCATION_CHARS, "");
|
|
556
|
+
if (cleaned === text) return {
|
|
557
|
+
action: "allow"
|
|
558
|
+
};
|
|
559
|
+
return {
|
|
560
|
+
action: "redact",
|
|
561
|
+
text: cleaned,
|
|
562
|
+
reason: "obfuscation characters normalized"
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
__name(unicodeNormalizer, "unicodeNormalizer");
|
|
568
|
+
function costGuard(options) {
|
|
569
|
+
let used = 0;
|
|
570
|
+
return {
|
|
571
|
+
name: "cost-guard",
|
|
572
|
+
// Returns a Promise explicitly (not `async`) so a budget breach REJECTS uniformly — never a
|
|
573
|
+
// sync throw — safe for direct callers and for the pipeline's `await g.checkInput()`.
|
|
574
|
+
checkInput(text) {
|
|
575
|
+
used += estimateTokens(text);
|
|
576
|
+
if (used > options.maxTokens) {
|
|
577
|
+
return Promise.reject(new CostBudgetExceededError(used, options.maxTokens));
|
|
578
|
+
}
|
|
579
|
+
return Promise.resolve({
|
|
580
|
+
action: "allow"
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
__name(costGuard, "costGuard");
|
|
586
|
+
function outputModeration(options) {
|
|
587
|
+
return {
|
|
588
|
+
name: "output-moderation",
|
|
589
|
+
async checkOutput(text) {
|
|
590
|
+
const flagged = await options.moderate(text);
|
|
591
|
+
return flagged ? {
|
|
592
|
+
action: "block",
|
|
593
|
+
reason: "output flagged by moderation predicate"
|
|
594
|
+
} : {
|
|
595
|
+
action: "allow"
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
__name(outputModeration, "outputModeration");
|
|
601
|
+
|
|
602
|
+
// src/guardrails/pipeline.ts
|
|
603
|
+
async function runInputGuards(text, guards) {
|
|
604
|
+
let current = text;
|
|
605
|
+
for (const g of guards) {
|
|
606
|
+
if (!g.checkInput) continue;
|
|
607
|
+
const r = await g.checkInput(current);
|
|
608
|
+
if (r.action === "block") {
|
|
609
|
+
throw new GuardrailViolationError(g.name, "input", r.reason ?? "blocked");
|
|
610
|
+
}
|
|
611
|
+
if (r.action === "redact" && r.text !== void 0) current = r.text;
|
|
612
|
+
}
|
|
613
|
+
return current;
|
|
614
|
+
}
|
|
615
|
+
__name(runInputGuards, "runInputGuards");
|
|
616
|
+
async function runOutputGuards(text, guards) {
|
|
617
|
+
let current = text;
|
|
618
|
+
for (const g of guards) {
|
|
619
|
+
if (!g.checkOutput) continue;
|
|
620
|
+
const r = await g.checkOutput(current);
|
|
621
|
+
if (r.action === "block") {
|
|
622
|
+
throw new GuardrailViolationError(g.name, "output", r.reason ?? "blocked");
|
|
623
|
+
}
|
|
624
|
+
if (r.action === "redact" && r.text !== void 0) current = r.text;
|
|
625
|
+
}
|
|
626
|
+
return current;
|
|
627
|
+
}
|
|
628
|
+
__name(runOutputGuards, "runOutputGuards");
|
|
629
|
+
|
|
630
|
+
// src/guardrails/stream.ts
|
|
631
|
+
async function* moderateOutputStream(inner, guards, extractText) {
|
|
632
|
+
const hasOutputGuard = guards.some((g) => g.checkOutput != null);
|
|
633
|
+
if (!hasOutputGuard) return yield* inner;
|
|
634
|
+
const buffered = [];
|
|
635
|
+
let accumulated = "";
|
|
636
|
+
let step = await inner.next();
|
|
637
|
+
while (!step.done) {
|
|
638
|
+
const event = step.value;
|
|
639
|
+
const text = extractText(event);
|
|
640
|
+
if (text !== void 0) accumulated += text;
|
|
641
|
+
buffered.push(event);
|
|
642
|
+
step = await inner.next();
|
|
643
|
+
}
|
|
644
|
+
await runOutputGuards(accumulated, guards);
|
|
645
|
+
for (const event of buffered) yield event;
|
|
646
|
+
return step.value;
|
|
647
|
+
}
|
|
648
|
+
__name(moderateOutputStream, "moderateOutputStream");
|
|
649
|
+
|
|
458
650
|
// src/bridge/tool-hooks-plugin.ts
|
|
459
651
|
function createToolHooksPlugin(hooks) {
|
|
460
652
|
return {
|
|
@@ -508,6 +700,33 @@ function createToolHooksPlugin(hooks) {
|
|
|
508
700
|
}
|
|
509
701
|
__name(createToolHooksPlugin, "createToolHooksPlugin");
|
|
510
702
|
|
|
703
|
+
// src/bridge/model-selection.ts
|
|
704
|
+
var PARAM_THINKING = "thinking";
|
|
705
|
+
function buildModelSelection(model, effort) {
|
|
706
|
+
const base = typeof model === "string" ? {
|
|
707
|
+
id: model
|
|
708
|
+
} : {
|
|
709
|
+
...model
|
|
710
|
+
};
|
|
711
|
+
if (!effort) return base;
|
|
712
|
+
return {
|
|
713
|
+
...base,
|
|
714
|
+
params: [
|
|
715
|
+
...base.params ?? [],
|
|
716
|
+
{
|
|
717
|
+
id: PARAM_THINKING,
|
|
718
|
+
value: effort
|
|
719
|
+
}
|
|
720
|
+
]
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
__name(buildModelSelection, "buildModelSelection");
|
|
724
|
+
function reasoningEffortOf(model) {
|
|
725
|
+
const params = typeof model === "string" ? void 0 : model.params;
|
|
726
|
+
return params?.find((p) => p.id === PARAM_THINKING)?.value;
|
|
727
|
+
}
|
|
728
|
+
__name(reasoningEffortOf, "reasoningEffortOf");
|
|
729
|
+
|
|
511
730
|
// src/bridge/event-translator.ts
|
|
512
731
|
function asString(value, fallback) {
|
|
513
732
|
if (typeof value === "string") return value;
|
|
@@ -551,7 +770,11 @@ function translateAssistantEvent(msg) {
|
|
|
551
770
|
if (b.type === "tool_use") {
|
|
552
771
|
events.push({
|
|
553
772
|
type: "tool_call",
|
|
554
|
-
|
|
773
|
+
// #138 — era `tc-${Date.now()}`. Um id novo a cada chamada NUNCA está no conjunto de
|
|
774
|
+
// dedup, então o fallback derrotava a dedup por construção — e ainda parecia um id de
|
|
775
|
+
// verdade para quem lê. String vazia é honesta: `isDuplicatedByDelta` a trata como
|
|
776
|
+
// "não sei identificar" e prefere um duplo-render visível a uma supressão silenciosa.
|
|
777
|
+
callId: b.id ?? "",
|
|
555
778
|
toolName: b.name ?? "unknown",
|
|
556
779
|
input: b.input ?? {}
|
|
557
780
|
});
|
|
@@ -562,7 +785,7 @@ function translateAssistantEvent(msg) {
|
|
|
562
785
|
__name(translateAssistantEvent, "translateAssistantEvent");
|
|
563
786
|
function translateToolCallEvent(msg) {
|
|
564
787
|
const status = msg.status;
|
|
565
|
-
const callId = asString(msg.call_id,
|
|
788
|
+
const callId = asString(msg.call_id, "");
|
|
566
789
|
const toolName = asString(msg.name, "unknown");
|
|
567
790
|
if (status === "completed") {
|
|
568
791
|
return [
|
|
@@ -631,6 +854,22 @@ function translateStatusEvent(msg) {
|
|
|
631
854
|
return [];
|
|
632
855
|
}
|
|
633
856
|
__name(translateStatusEvent, "translateStatusEvent");
|
|
857
|
+
var jaAvisados = /* @__PURE__ */ new Set();
|
|
858
|
+
function avisarSeDesconhecido(tipo, ignoradosDeProposito) {
|
|
859
|
+
if (ignoradosDeProposito.has(tipo) || jaAvisados.has(tipo)) return;
|
|
860
|
+
jaAvisados.add(tipo);
|
|
861
|
+
console.warn(`[theokit] agents.bridge: evento "${tipo}" do SDK n\xE3o \xE9 traduzido e foi descartado. Se ele carrega informa\xE7\xE3o que a UI precisa, o tradutor precisa de um caso para ele (#141).`);
|
|
862
|
+
}
|
|
863
|
+
__name(avisarSeDesconhecido, "avisarSeDesconhecido");
|
|
864
|
+
var SDK_MESSAGE_IGNORADOS = /* @__PURE__ */ new Set([
|
|
865
|
+
"user"
|
|
866
|
+
]);
|
|
867
|
+
var INTERACTION_UPDATE_IGNORADOS = /* @__PURE__ */ new Set([
|
|
868
|
+
"thinking-completed",
|
|
869
|
+
"token-delta",
|
|
870
|
+
"step-started",
|
|
871
|
+
"step-completed"
|
|
872
|
+
]);
|
|
634
873
|
function translateSdkEvent(msg, runId) {
|
|
635
874
|
switch (msg.type) {
|
|
636
875
|
case "system":
|
|
@@ -648,7 +887,31 @@ function translateSdkEvent(msg, runId) {
|
|
|
648
887
|
];
|
|
649
888
|
case "status":
|
|
650
889
|
return translateStatusEvent(msg);
|
|
890
|
+
case "request":
|
|
891
|
+
return [
|
|
892
|
+
{
|
|
893
|
+
type: "input_requested",
|
|
894
|
+
requestId: asString(msg.request_id, "")
|
|
895
|
+
}
|
|
896
|
+
];
|
|
897
|
+
case "task": {
|
|
898
|
+
const status = typeof msg.status === "string" ? msg.status : void 0;
|
|
899
|
+
const text = typeof msg.text === "string" ? msg.text : void 0;
|
|
900
|
+
if (status === void 0 && text === void 0) return [];
|
|
901
|
+
return [
|
|
902
|
+
{
|
|
903
|
+
type: "task_progress",
|
|
904
|
+
...status !== void 0 ? {
|
|
905
|
+
status
|
|
906
|
+
} : {},
|
|
907
|
+
...text !== void 0 ? {
|
|
908
|
+
text
|
|
909
|
+
} : {}
|
|
910
|
+
}
|
|
911
|
+
];
|
|
912
|
+
}
|
|
651
913
|
default:
|
|
914
|
+
avisarSeDesconhecido(msg.type, SDK_MESSAGE_IGNORADOS);
|
|
652
915
|
return [];
|
|
653
916
|
}
|
|
654
917
|
}
|
|
@@ -698,39 +961,20 @@ function translateInteractionUpdate(update) {
|
|
|
698
961
|
isError: false
|
|
699
962
|
}
|
|
700
963
|
];
|
|
964
|
+
case "shell-output-delta":
|
|
965
|
+
return [
|
|
966
|
+
{
|
|
967
|
+
type: "shell_output",
|
|
968
|
+
event: update.event
|
|
969
|
+
}
|
|
970
|
+
];
|
|
701
971
|
default:
|
|
972
|
+
avisarSeDesconhecido(update.type, INTERACTION_UPDATE_IGNORADOS);
|
|
702
973
|
return [];
|
|
703
974
|
}
|
|
704
975
|
}
|
|
705
976
|
__name(translateInteractionUpdate, "translateInteractionUpdate");
|
|
706
977
|
|
|
707
|
-
// src/bridge/model-selection.ts
|
|
708
|
-
var PARAM_THINKING = "thinking";
|
|
709
|
-
function buildModelSelection(model, effort) {
|
|
710
|
-
const base = typeof model === "string" ? {
|
|
711
|
-
id: model
|
|
712
|
-
} : {
|
|
713
|
-
...model
|
|
714
|
-
};
|
|
715
|
-
if (!effort) return base;
|
|
716
|
-
return {
|
|
717
|
-
...base,
|
|
718
|
-
params: [
|
|
719
|
-
...base.params ?? [],
|
|
720
|
-
{
|
|
721
|
-
id: PARAM_THINKING,
|
|
722
|
-
value: effort
|
|
723
|
-
}
|
|
724
|
-
]
|
|
725
|
-
};
|
|
726
|
-
}
|
|
727
|
-
__name(buildModelSelection, "buildModelSelection");
|
|
728
|
-
function reasoningEffortOf(model) {
|
|
729
|
-
const params = typeof model === "string" ? void 0 : model.params;
|
|
730
|
-
return params?.find((p) => p.id === PARAM_THINKING)?.value;
|
|
731
|
-
}
|
|
732
|
-
__name(reasoningEffortOf, "reasoningEffortOf");
|
|
733
|
-
|
|
734
978
|
// src/bridge/think-tag-extractor.ts
|
|
735
979
|
var TAG = "think";
|
|
736
980
|
var OPEN = `<${TAG}>`;
|
|
@@ -1059,6 +1303,134 @@ function realUsageDone(result, t0) {
|
|
|
1059
1303
|
}
|
|
1060
1304
|
__name(realUsageDone, "realUsageDone");
|
|
1061
1305
|
|
|
1306
|
+
// src/bridge/sdk-adapter-merge.ts
|
|
1307
|
+
function createAsyncQueue() {
|
|
1308
|
+
const items = [];
|
|
1309
|
+
let wake = null;
|
|
1310
|
+
let closed = false;
|
|
1311
|
+
return {
|
|
1312
|
+
push(item) {
|
|
1313
|
+
items.push(item);
|
|
1314
|
+
if (wake) {
|
|
1315
|
+
wake();
|
|
1316
|
+
wake = null;
|
|
1317
|
+
}
|
|
1318
|
+
},
|
|
1319
|
+
close() {
|
|
1320
|
+
closed = true;
|
|
1321
|
+
if (wake) {
|
|
1322
|
+
wake();
|
|
1323
|
+
wake = null;
|
|
1324
|
+
}
|
|
1325
|
+
},
|
|
1326
|
+
async *[Symbol.asyncIterator]() {
|
|
1327
|
+
for (; ; ) {
|
|
1328
|
+
while (items.length > 0) {
|
|
1329
|
+
const next = items.shift();
|
|
1330
|
+
if (next !== void 0) yield next;
|
|
1331
|
+
}
|
|
1332
|
+
if (closed) return;
|
|
1333
|
+
await new Promise((resolve) => {
|
|
1334
|
+
wake = resolve;
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
__name(createAsyncQueue, "createAsyncQueue");
|
|
1341
|
+
function streamCallId(ev) {
|
|
1342
|
+
return typeof ev.callId === "string" ? ev.callId : "";
|
|
1343
|
+
}
|
|
1344
|
+
__name(streamCallId, "streamCallId");
|
|
1345
|
+
function idsDaMesmaChamada(ev, update) {
|
|
1346
|
+
const ids = [];
|
|
1347
|
+
const call = streamCallId(ev);
|
|
1348
|
+
if (call !== "") ids.push(call);
|
|
1349
|
+
const model = update?.modelCallId;
|
|
1350
|
+
if (typeof model === "string" && model !== "" && model !== call) ids.push(model);
|
|
1351
|
+
return ids;
|
|
1352
|
+
}
|
|
1353
|
+
__name(idsDaMesmaChamada, "idsDaMesmaChamada");
|
|
1354
|
+
function isDuplicatedByDelta(ev, state) {
|
|
1355
|
+
if (ev.type === "text_delta") return state.sawTextDelta;
|
|
1356
|
+
if (ev.type === "thinking") return state.sawThinkingDelta;
|
|
1357
|
+
if (ev.type === "tool_call") {
|
|
1358
|
+
const id = streamCallId(ev);
|
|
1359
|
+
return id !== "" && state.emittedToolCallIds.has(id);
|
|
1360
|
+
}
|
|
1361
|
+
if (ev.type === "tool_result") {
|
|
1362
|
+
const id = streamCallId(ev);
|
|
1363
|
+
return id !== "" && state.emittedToolResultIds.has(id);
|
|
1364
|
+
}
|
|
1365
|
+
return false;
|
|
1366
|
+
}
|
|
1367
|
+
__name(isDuplicatedByDelta, "isDuplicatedByDelta");
|
|
1368
|
+
async function* mergeDeltaStream(queue, openStream, runId, state) {
|
|
1369
|
+
let pumpError;
|
|
1370
|
+
const pump = (async () => {
|
|
1371
|
+
try {
|
|
1372
|
+
const stream = await openStream();
|
|
1373
|
+
for await (const msg of stream) queue.push({
|
|
1374
|
+
kind: "sdk",
|
|
1375
|
+
msg
|
|
1376
|
+
});
|
|
1377
|
+
} finally {
|
|
1378
|
+
queue.close();
|
|
1379
|
+
}
|
|
1380
|
+
})().catch((thrown) => {
|
|
1381
|
+
pumpError = {
|
|
1382
|
+
thrown
|
|
1383
|
+
};
|
|
1384
|
+
});
|
|
1385
|
+
for await (const item of queue) {
|
|
1386
|
+
if (item.kind === "delta") {
|
|
1387
|
+
state.lastEventType = item.event.type;
|
|
1388
|
+
yield item.event;
|
|
1389
|
+
continue;
|
|
1390
|
+
}
|
|
1391
|
+
for (const out of translateSdkEvent(item.msg, runId)) {
|
|
1392
|
+
if (out.type === "done") continue;
|
|
1393
|
+
if (isDuplicatedByDelta(out, state)) continue;
|
|
1394
|
+
if (out.type === "error") state.sawError = true;
|
|
1395
|
+
state.lastEventType = out.type;
|
|
1396
|
+
yield out;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
await pump;
|
|
1400
|
+
if (pumpError) throw pumpError.thrown;
|
|
1401
|
+
}
|
|
1402
|
+
__name(mergeDeltaStream, "mergeDeltaStream");
|
|
1403
|
+
function createDeltaSink(queue) {
|
|
1404
|
+
const state = {
|
|
1405
|
+
sawTextDelta: false,
|
|
1406
|
+
sawThinkingDelta: false,
|
|
1407
|
+
emittedToolCallIds: /* @__PURE__ */ new Set(),
|
|
1408
|
+
emittedToolResultIds: /* @__PURE__ */ new Set(),
|
|
1409
|
+
sawError: false,
|
|
1410
|
+
lastEventType: ""
|
|
1411
|
+
};
|
|
1412
|
+
const onDelta = /* @__PURE__ */ __name((d) => {
|
|
1413
|
+
for (const event of translateInteractionUpdate(d.update)) {
|
|
1414
|
+
if (event.type === "text_delta") state.sawTextDelta = true;
|
|
1415
|
+
else if (event.type === "thinking") state.sawThinkingDelta = true;
|
|
1416
|
+
else if (event.type === "tool_call") {
|
|
1417
|
+
for (const id of idsDaMesmaChamada(event, d.update)) state.emittedToolCallIds.add(id);
|
|
1418
|
+
} else if (event.type === "tool_result") {
|
|
1419
|
+
for (const id of idsDaMesmaChamada(event, d.update)) state.emittedToolResultIds.add(id);
|
|
1420
|
+
}
|
|
1421
|
+
queue.push({
|
|
1422
|
+
kind: "delta",
|
|
1423
|
+
event
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
}, "onDelta");
|
|
1427
|
+
return {
|
|
1428
|
+
state,
|
|
1429
|
+
onDelta
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1432
|
+
__name(createDeltaSink, "createDeltaSink");
|
|
1433
|
+
|
|
1062
1434
|
// src/bridge/tool-dialect-stripper.ts
|
|
1063
1435
|
var OPEN2 = "<function=";
|
|
1064
1436
|
var CLOSE2 = "</tool_call>";
|
|
@@ -1207,122 +1579,6 @@ async function loadSdkRuntime() {
|
|
|
1207
1579
|
}
|
|
1208
1580
|
}
|
|
1209
1581
|
__name(loadSdkRuntime, "loadSdkRuntime");
|
|
1210
|
-
function createAsyncQueue() {
|
|
1211
|
-
const items = [];
|
|
1212
|
-
let wake = null;
|
|
1213
|
-
let closed = false;
|
|
1214
|
-
return {
|
|
1215
|
-
push(item) {
|
|
1216
|
-
items.push(item);
|
|
1217
|
-
if (wake) {
|
|
1218
|
-
wake();
|
|
1219
|
-
wake = null;
|
|
1220
|
-
}
|
|
1221
|
-
},
|
|
1222
|
-
close() {
|
|
1223
|
-
closed = true;
|
|
1224
|
-
if (wake) {
|
|
1225
|
-
wake();
|
|
1226
|
-
wake = null;
|
|
1227
|
-
}
|
|
1228
|
-
},
|
|
1229
|
-
async *[Symbol.asyncIterator]() {
|
|
1230
|
-
for (; ; ) {
|
|
1231
|
-
while (items.length > 0) {
|
|
1232
|
-
const next = items.shift();
|
|
1233
|
-
if (next !== void 0) yield next;
|
|
1234
|
-
}
|
|
1235
|
-
if (closed) return;
|
|
1236
|
-
await new Promise((resolve) => {
|
|
1237
|
-
wake = resolve;
|
|
1238
|
-
});
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
};
|
|
1242
|
-
}
|
|
1243
|
-
__name(createAsyncQueue, "createAsyncQueue");
|
|
1244
|
-
function streamCallId(ev) {
|
|
1245
|
-
return typeof ev.callId === "string" ? ev.callId : "";
|
|
1246
|
-
}
|
|
1247
|
-
__name(streamCallId, "streamCallId");
|
|
1248
|
-
function isDuplicatedByDelta(ev, state) {
|
|
1249
|
-
if (ev.type === "text_delta") return state.sawTextDelta;
|
|
1250
|
-
if (ev.type === "thinking") return state.sawThinkingDelta;
|
|
1251
|
-
if (ev.type === "tool_call") {
|
|
1252
|
-
const id = streamCallId(ev);
|
|
1253
|
-
return id !== "" && state.emittedToolCallIds.has(id);
|
|
1254
|
-
}
|
|
1255
|
-
if (ev.type === "tool_result") {
|
|
1256
|
-
const id = streamCallId(ev);
|
|
1257
|
-
return id !== "" && state.emittedToolResultIds.has(id);
|
|
1258
|
-
}
|
|
1259
|
-
return false;
|
|
1260
|
-
}
|
|
1261
|
-
__name(isDuplicatedByDelta, "isDuplicatedByDelta");
|
|
1262
|
-
async function* mergeDeltaStream(queue, openStream, runId, state) {
|
|
1263
|
-
let pumpError;
|
|
1264
|
-
const pump = (async () => {
|
|
1265
|
-
try {
|
|
1266
|
-
const stream = await openStream();
|
|
1267
|
-
for await (const msg of stream) queue.push({
|
|
1268
|
-
kind: "sdk",
|
|
1269
|
-
msg
|
|
1270
|
-
});
|
|
1271
|
-
} finally {
|
|
1272
|
-
queue.close();
|
|
1273
|
-
}
|
|
1274
|
-
})().catch((thrown) => {
|
|
1275
|
-
pumpError = {
|
|
1276
|
-
thrown
|
|
1277
|
-
};
|
|
1278
|
-
});
|
|
1279
|
-
for await (const item of queue) {
|
|
1280
|
-
if (item.kind === "delta") {
|
|
1281
|
-
yield item.event;
|
|
1282
|
-
continue;
|
|
1283
|
-
}
|
|
1284
|
-
for (const out of translateSdkEvent(item.msg, runId)) {
|
|
1285
|
-
if (out.type === "done") continue;
|
|
1286
|
-
if (isDuplicatedByDelta(out, state)) continue;
|
|
1287
|
-
if (out.type === "error") state.sawError = true;
|
|
1288
|
-
yield out;
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
await pump;
|
|
1292
|
-
if (pumpError) throw pumpError.thrown;
|
|
1293
|
-
}
|
|
1294
|
-
__name(mergeDeltaStream, "mergeDeltaStream");
|
|
1295
|
-
function createDeltaSink(queue) {
|
|
1296
|
-
const state = {
|
|
1297
|
-
sawTextDelta: false,
|
|
1298
|
-
sawThinkingDelta: false,
|
|
1299
|
-
emittedToolCallIds: /* @__PURE__ */ new Set(),
|
|
1300
|
-
emittedToolResultIds: /* @__PURE__ */ new Set(),
|
|
1301
|
-
sawError: false
|
|
1302
|
-
};
|
|
1303
|
-
const onDelta = /* @__PURE__ */ __name((d) => {
|
|
1304
|
-
for (const event of translateInteractionUpdate(d.update)) {
|
|
1305
|
-
if (event.type === "text_delta") state.sawTextDelta = true;
|
|
1306
|
-
else if (event.type === "thinking") state.sawThinkingDelta = true;
|
|
1307
|
-
else if (event.type === "tool_call") {
|
|
1308
|
-
const id = streamCallId(event);
|
|
1309
|
-
if (id !== "") state.emittedToolCallIds.add(id);
|
|
1310
|
-
} else if (event.type === "tool_result") {
|
|
1311
|
-
const id = streamCallId(event);
|
|
1312
|
-
if (id !== "") state.emittedToolResultIds.add(id);
|
|
1313
|
-
}
|
|
1314
|
-
queue.push({
|
|
1315
|
-
kind: "delta",
|
|
1316
|
-
event
|
|
1317
|
-
});
|
|
1318
|
-
}
|
|
1319
|
-
}, "onDelta");
|
|
1320
|
-
return {
|
|
1321
|
-
state,
|
|
1322
|
-
onDelta
|
|
1323
|
-
};
|
|
1324
|
-
}
|
|
1325
|
-
__name(createDeltaSink, "createDeltaSink");
|
|
1326
1582
|
function resolveTextTransformFlags(compiled, overrides) {
|
|
1327
1583
|
return {
|
|
1328
1584
|
parseThinkTags: overrides.parseThinkTags ?? compiled.parseThinkTags ?? false,
|
|
@@ -1466,6 +1722,7 @@ async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
|
|
|
1466
1722
|
onDelta
|
|
1467
1723
|
};
|
|
1468
1724
|
if (factoryOpts?.disableTools === true) sendOptions.toolChoice = "none";
|
|
1725
|
+
if (overrides.onRunEvent !== void 0) sendOptions.onRunEvent = overrides.onRunEvent;
|
|
1469
1726
|
const sendInput = overrides.images && overrides.images.length > 0 ? {
|
|
1470
1727
|
text: message,
|
|
1471
1728
|
images: overrides.images
|
|
@@ -1479,7 +1736,16 @@ async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
|
|
|
1479
1736
|
})) {
|
|
1480
1737
|
yield event;
|
|
1481
1738
|
}
|
|
1482
|
-
if (
|
|
1739
|
+
if (state.sawError) {
|
|
1740
|
+
if (state.lastEventType !== "error") {
|
|
1741
|
+
yield {
|
|
1742
|
+
type: "error",
|
|
1743
|
+
code: "RUN_FAILED",
|
|
1744
|
+
message: "O turno terminou com erro; veja o evento `error` anterior.",
|
|
1745
|
+
retryable: false
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1748
|
+
} else {
|
|
1483
1749
|
yield realUsageDone(await (await sendPromise).wait(), t0);
|
|
1484
1750
|
}
|
|
1485
1751
|
} finally {
|
|
@@ -1519,10 +1785,34 @@ function toAgentFactory(def, opts) {
|
|
|
1519
1785
|
...m8,
|
|
1520
1786
|
...extra
|
|
1521
1787
|
});
|
|
1522
|
-
return agent;
|
|
1788
|
+
return withGuardrails(agent, compiled.guardrails);
|
|
1523
1789
|
};
|
|
1524
1790
|
}
|
|
1525
1791
|
__name(toAgentFactory, "toAgentFactory");
|
|
1792
|
+
function withGuardrails(handle, guardrails) {
|
|
1793
|
+
if (guardrails === void 0 || guardrails.length === 0) return handle;
|
|
1794
|
+
return {
|
|
1795
|
+
get agentId() {
|
|
1796
|
+
return handle.agentId;
|
|
1797
|
+
},
|
|
1798
|
+
dispose: /* @__PURE__ */ __name(() => handle.dispose(), "dispose"),
|
|
1799
|
+
send: /* @__PURE__ */ __name(async (msg, sendOpts) => {
|
|
1800
|
+
const guarded = await runInputGuards(msg, guardrails);
|
|
1801
|
+
const turn = await handle.send(guarded, sendOpts);
|
|
1802
|
+
return {
|
|
1803
|
+
wait: /* @__PURE__ */ __name(async () => {
|
|
1804
|
+
const out = await turn.wait();
|
|
1805
|
+
if (out.result === void 0) return out;
|
|
1806
|
+
return {
|
|
1807
|
+
...out,
|
|
1808
|
+
result: await runOutputGuards(out.result, guardrails)
|
|
1809
|
+
};
|
|
1810
|
+
}, "wait")
|
|
1811
|
+
};
|
|
1812
|
+
}, "send")
|
|
1813
|
+
};
|
|
1814
|
+
}
|
|
1815
|
+
__name(withGuardrails, "withGuardrails");
|
|
1526
1816
|
|
|
1527
1817
|
// ../presenter/dist/index.js
|
|
1528
1818
|
var __defProp = Object.defineProperty;
|
|
@@ -2089,6 +2379,61 @@ function doneToMetadata(event) {
|
|
|
2089
2379
|
};
|
|
2090
2380
|
}
|
|
2091
2381
|
__name(doneToMetadata, "doneToMetadata");
|
|
2382
|
+
var ERROR_CODE_DATA_PART = "data-error-code";
|
|
2383
|
+
var INPUT_REQUESTED_DATA_PART = "data-input-requested";
|
|
2384
|
+
var TASK_PROGRESS_DATA_PART = "data-task-progress";
|
|
2385
|
+
var SHELL_OUTPUT_DATA_PART = "data-shell-output";
|
|
2386
|
+
function dataPart(type, data) {
|
|
2387
|
+
return {
|
|
2388
|
+
type,
|
|
2389
|
+
data,
|
|
2390
|
+
transient: true
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
__name(dataPart, "dataPart");
|
|
2394
|
+
function* errorChunks(errorText, code) {
|
|
2395
|
+
if (code !== void 0) yield dataPart(ERROR_CODE_DATA_PART, {
|
|
2396
|
+
code
|
|
2397
|
+
});
|
|
2398
|
+
yield {
|
|
2399
|
+
type: "error",
|
|
2400
|
+
errorText
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
__name(errorChunks, "errorChunks");
|
|
2404
|
+
function diagnosticDataPart(event) {
|
|
2405
|
+
switch (event.type) {
|
|
2406
|
+
case "checkpoint_saved":
|
|
2407
|
+
return dataPart("data-checkpoint", {
|
|
2408
|
+
checkpointId: event.checkpointId,
|
|
2409
|
+
resumeToken: event.resumeToken,
|
|
2410
|
+
step: event.step
|
|
2411
|
+
});
|
|
2412
|
+
// theokit#141 — without these cases the three restored events would be dropped by the loop's
|
|
2413
|
+
// catch-all, which is the reported defect one layer down: translating an event and never
|
|
2414
|
+
// presenting it leaves the consumer just as blind, minus even the warning.
|
|
2415
|
+
case "input_requested":
|
|
2416
|
+
return dataPart(INPUT_REQUESTED_DATA_PART, {
|
|
2417
|
+
requestId: event.requestId
|
|
2418
|
+
});
|
|
2419
|
+
case "task_progress":
|
|
2420
|
+
return dataPart(TASK_PROGRESS_DATA_PART, {
|
|
2421
|
+
...event.status !== void 0 ? {
|
|
2422
|
+
status: event.status
|
|
2423
|
+
} : {},
|
|
2424
|
+
...event.text !== void 0 ? {
|
|
2425
|
+
text: event.text
|
|
2426
|
+
} : {}
|
|
2427
|
+
});
|
|
2428
|
+
case "shell_output":
|
|
2429
|
+
return dataPart(SHELL_OUTPUT_DATA_PART, {
|
|
2430
|
+
event: event.event
|
|
2431
|
+
});
|
|
2432
|
+
default:
|
|
2433
|
+
return null;
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
__name(diagnosticDataPart, "diagnosticDataPart");
|
|
2092
2437
|
async function* presentUIMessageStream(events, opts) {
|
|
2093
2438
|
const presenter = new UIMessageStreamPresenter({
|
|
2094
2439
|
textId: opts.textId
|
|
@@ -2123,28 +2468,14 @@ async function* presentUIMessageStream(events, opts) {
|
|
|
2123
2468
|
};
|
|
2124
2469
|
continue;
|
|
2125
2470
|
}
|
|
2126
|
-
|
|
2471
|
+
const diagnostic = diagnosticDataPart(event);
|
|
2472
|
+
if (diagnostic !== null) {
|
|
2127
2473
|
yield* presenter.closeBlock();
|
|
2128
|
-
yield
|
|
2129
|
-
type: "data-checkpoint",
|
|
2130
|
-
data: {
|
|
2131
|
-
checkpointId: event.checkpointId,
|
|
2132
|
-
resumeToken: event.resumeToken,
|
|
2133
|
-
step: event.step
|
|
2134
|
-
},
|
|
2135
|
-
transient: true
|
|
2136
|
-
};
|
|
2474
|
+
yield diagnostic;
|
|
2137
2475
|
continue;
|
|
2138
2476
|
}
|
|
2139
2477
|
if (event.type === "error") {
|
|
2140
|
-
|
|
2141
|
-
yield {
|
|
2142
|
-
type: "error",
|
|
2143
|
-
errorText: event.message,
|
|
2144
|
-
...code !== void 0 ? {
|
|
2145
|
-
errorCode: code
|
|
2146
|
-
} : {}
|
|
2147
|
-
};
|
|
2478
|
+
yield* errorChunks(event.message, event.code);
|
|
2148
2479
|
break;
|
|
2149
2480
|
}
|
|
2150
2481
|
if (event.type === "done") {
|
|
@@ -2154,13 +2485,7 @@ async function* presentUIMessageStream(events, opts) {
|
|
|
2154
2485
|
}
|
|
2155
2486
|
} catch (err) {
|
|
2156
2487
|
const code = err.code;
|
|
2157
|
-
yield
|
|
2158
|
-
type: "error",
|
|
2159
|
-
errorText: String(err),
|
|
2160
|
-
...typeof code === "string" ? {
|
|
2161
|
-
errorCode: code
|
|
2162
|
-
} : {}
|
|
2163
|
-
};
|
|
2488
|
+
yield* errorChunks(String(err), typeof code === "string" ? code : void 0);
|
|
2164
2489
|
}
|
|
2165
2490
|
yield* presenter.finish(turnMetadata);
|
|
2166
2491
|
}
|
|
@@ -2364,6 +2689,7 @@ function streamAgentUIMessages(compiled, apiKey, input) {
|
|
|
2364
2689
|
if (input.cwd !== void 0) overrides.cwd = input.cwd;
|
|
2365
2690
|
if (input.baseDir !== void 0) overrides.baseDir = input.baseDir;
|
|
2366
2691
|
if (input.images !== void 0) overrides.images = input.images;
|
|
2692
|
+
if (input.onRunEvent !== void 0) overrides.onRunEvent = input.onRunEvent;
|
|
2367
2693
|
let source;
|
|
2368
2694
|
if (!input.hitl || input.hitl.gated.size === 0) {
|
|
2369
2695
|
const events2 = createSdkAgentStream(compiled, compiled.tools, apiKey, overrides)(input.message, input.sessionId);
|
|
@@ -2414,198 +2740,6 @@ function streamAgentUIMessages(compiled, apiKey, input) {
|
|
|
2414
2740
|
}
|
|
2415
2741
|
__name(streamAgentUIMessages, "streamAgentUIMessages");
|
|
2416
2742
|
|
|
2417
|
-
// src/guardrails/types.ts
|
|
2418
|
-
var GuardrailViolationError = class extends Error {
|
|
2419
|
-
static {
|
|
2420
|
-
__name(this, "GuardrailViolationError");
|
|
2421
|
-
}
|
|
2422
|
-
guardName;
|
|
2423
|
-
phase;
|
|
2424
|
-
reason;
|
|
2425
|
-
constructor(guardName, phase, reason) {
|
|
2426
|
-
super(`Guardrail "${guardName}" blocked ${phase}: ${reason}`), this.guardName = guardName, this.phase = phase, this.reason = reason;
|
|
2427
|
-
this.name = "GuardrailViolationError";
|
|
2428
|
-
}
|
|
2429
|
-
};
|
|
2430
|
-
var CostBudgetExceededError = class extends Error {
|
|
2431
|
-
static {
|
|
2432
|
-
__name(this, "CostBudgetExceededError");
|
|
2433
|
-
}
|
|
2434
|
-
usedTokens;
|
|
2435
|
-
maxTokens;
|
|
2436
|
-
constructor(usedTokens, maxTokens) {
|
|
2437
|
-
super(`Cost budget exceeded: ${usedTokens} > ${maxTokens} tokens`), this.usedTokens = usedTokens, this.maxTokens = maxTokens;
|
|
2438
|
-
this.name = "CostBudgetExceededError";
|
|
2439
|
-
}
|
|
2440
|
-
};
|
|
2441
|
-
|
|
2442
|
-
// src/guardrails/detectors.ts
|
|
2443
|
-
function estimateTokens(text) {
|
|
2444
|
-
return Math.ceil(text.length / 4);
|
|
2445
|
-
}
|
|
2446
|
-
__name(estimateTokens, "estimateTokens");
|
|
2447
|
-
var INJECTION_PHRASES = [
|
|
2448
|
-
"previous instructions",
|
|
2449
|
-
"disregard the above",
|
|
2450
|
-
"you are now dan",
|
|
2451
|
-
"system prompt",
|
|
2452
|
-
"no restrictions",
|
|
2453
|
-
"without restrictions",
|
|
2454
|
-
"no rules",
|
|
2455
|
-
"override your"
|
|
2456
|
-
];
|
|
2457
|
-
function normalizeForMatch(text) {
|
|
2458
|
-
return text.toLowerCase().replace(/\s+/g, " ");
|
|
2459
|
-
}
|
|
2460
|
-
__name(normalizeForMatch, "normalizeForMatch");
|
|
2461
|
-
function promptInjectionDetector(options = {}) {
|
|
2462
|
-
const phrases = [
|
|
2463
|
-
...INJECTION_PHRASES,
|
|
2464
|
-
...(options.extra ?? []).map((p) => p.toLowerCase())
|
|
2465
|
-
];
|
|
2466
|
-
return {
|
|
2467
|
-
name: "prompt-injection",
|
|
2468
|
-
checkInput(text) {
|
|
2469
|
-
const normalized = normalizeForMatch(text);
|
|
2470
|
-
for (const phrase of phrases) {
|
|
2471
|
-
if (normalized.includes(phrase)) {
|
|
2472
|
-
return {
|
|
2473
|
-
action: "block",
|
|
2474
|
-
reason: `prompt injection phrase matched: "${phrase}"`
|
|
2475
|
-
};
|
|
2476
|
-
}
|
|
2477
|
-
}
|
|
2478
|
-
return {
|
|
2479
|
-
action: "allow"
|
|
2480
|
-
};
|
|
2481
|
-
}
|
|
2482
|
-
};
|
|
2483
|
-
}
|
|
2484
|
-
__name(promptInjectionDetector, "promptInjectionDetector");
|
|
2485
|
-
var CPF = /\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b/g;
|
|
2486
|
-
var EMAIL = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g;
|
|
2487
|
-
var PHONE = /\+?\d[\d\s()-]{7,13}\d/g;
|
|
2488
|
-
function piiDetector(options = {}) {
|
|
2489
|
-
const placeholder = options.placeholder ?? "[REDACTED]";
|
|
2490
|
-
return {
|
|
2491
|
-
name: "pii",
|
|
2492
|
-
checkInput(text) {
|
|
2493
|
-
let redacted = text;
|
|
2494
|
-
redacted = redacted.replace(EMAIL, placeholder);
|
|
2495
|
-
redacted = redacted.replace(CPF, placeholder);
|
|
2496
|
-
redacted = redacted.replace(PHONE, placeholder);
|
|
2497
|
-
if (redacted === text) return {
|
|
2498
|
-
action: "allow"
|
|
2499
|
-
};
|
|
2500
|
-
return {
|
|
2501
|
-
action: "redact",
|
|
2502
|
-
text: redacted,
|
|
2503
|
-
reason: "PII detected and redacted"
|
|
2504
|
-
};
|
|
2505
|
-
}
|
|
2506
|
-
};
|
|
2507
|
-
}
|
|
2508
|
-
__name(piiDetector, "piiDetector");
|
|
2509
|
-
var OBFUSCATION_CHARS = /[\u200B-\u200D\uFEFF\u202A-\u202E\u2066-\u2069]/g;
|
|
2510
|
-
function unicodeNormalizer() {
|
|
2511
|
-
return {
|
|
2512
|
-
name: "unicode-normalizer",
|
|
2513
|
-
checkInput(text) {
|
|
2514
|
-
const cleaned = text.normalize("NFKC").replace(OBFUSCATION_CHARS, "");
|
|
2515
|
-
if (cleaned === text) return {
|
|
2516
|
-
action: "allow"
|
|
2517
|
-
};
|
|
2518
|
-
return {
|
|
2519
|
-
action: "redact",
|
|
2520
|
-
text: cleaned,
|
|
2521
|
-
reason: "obfuscation characters normalized"
|
|
2522
|
-
};
|
|
2523
|
-
}
|
|
2524
|
-
};
|
|
2525
|
-
}
|
|
2526
|
-
__name(unicodeNormalizer, "unicodeNormalizer");
|
|
2527
|
-
function costGuard(options) {
|
|
2528
|
-
let used = 0;
|
|
2529
|
-
return {
|
|
2530
|
-
name: "cost-guard",
|
|
2531
|
-
// Returns a Promise explicitly (not `async`) so a budget breach REJECTS uniformly — never a
|
|
2532
|
-
// sync throw — safe for direct callers and for the pipeline's `await g.checkInput()`.
|
|
2533
|
-
checkInput(text) {
|
|
2534
|
-
used += estimateTokens(text);
|
|
2535
|
-
if (used > options.maxTokens) {
|
|
2536
|
-
return Promise.reject(new CostBudgetExceededError(used, options.maxTokens));
|
|
2537
|
-
}
|
|
2538
|
-
return Promise.resolve({
|
|
2539
|
-
action: "allow"
|
|
2540
|
-
});
|
|
2541
|
-
}
|
|
2542
|
-
};
|
|
2543
|
-
}
|
|
2544
|
-
__name(costGuard, "costGuard");
|
|
2545
|
-
function outputModeration(options) {
|
|
2546
|
-
return {
|
|
2547
|
-
name: "output-moderation",
|
|
2548
|
-
async checkOutput(text) {
|
|
2549
|
-
const flagged = await options.moderate(text);
|
|
2550
|
-
return flagged ? {
|
|
2551
|
-
action: "block",
|
|
2552
|
-
reason: "output flagged by moderation predicate"
|
|
2553
|
-
} : {
|
|
2554
|
-
action: "allow"
|
|
2555
|
-
};
|
|
2556
|
-
}
|
|
2557
|
-
};
|
|
2558
|
-
}
|
|
2559
|
-
__name(outputModeration, "outputModeration");
|
|
2560
|
-
|
|
2561
|
-
// src/guardrails/pipeline.ts
|
|
2562
|
-
async function runInputGuards(text, guards) {
|
|
2563
|
-
let current = text;
|
|
2564
|
-
for (const g of guards) {
|
|
2565
|
-
if (!g.checkInput) continue;
|
|
2566
|
-
const r = await g.checkInput(current);
|
|
2567
|
-
if (r.action === "block") {
|
|
2568
|
-
throw new GuardrailViolationError(g.name, "input", r.reason ?? "blocked");
|
|
2569
|
-
}
|
|
2570
|
-
if (r.action === "redact" && r.text !== void 0) current = r.text;
|
|
2571
|
-
}
|
|
2572
|
-
return current;
|
|
2573
|
-
}
|
|
2574
|
-
__name(runInputGuards, "runInputGuards");
|
|
2575
|
-
async function runOutputGuards(text, guards) {
|
|
2576
|
-
let current = text;
|
|
2577
|
-
for (const g of guards) {
|
|
2578
|
-
if (!g.checkOutput) continue;
|
|
2579
|
-
const r = await g.checkOutput(current);
|
|
2580
|
-
if (r.action === "block") {
|
|
2581
|
-
throw new GuardrailViolationError(g.name, "output", r.reason ?? "blocked");
|
|
2582
|
-
}
|
|
2583
|
-
if (r.action === "redact" && r.text !== void 0) current = r.text;
|
|
2584
|
-
}
|
|
2585
|
-
return current;
|
|
2586
|
-
}
|
|
2587
|
-
__name(runOutputGuards, "runOutputGuards");
|
|
2588
|
-
|
|
2589
|
-
// src/guardrails/stream.ts
|
|
2590
|
-
async function* moderateOutputStream(inner, guards, extractText) {
|
|
2591
|
-
const hasOutputGuard = guards.some((g) => g.checkOutput != null);
|
|
2592
|
-
if (!hasOutputGuard) return yield* inner;
|
|
2593
|
-
const buffered = [];
|
|
2594
|
-
let accumulated = "";
|
|
2595
|
-
let step = await inner.next();
|
|
2596
|
-
while (!step.done) {
|
|
2597
|
-
const event = step.value;
|
|
2598
|
-
const text = extractText(event);
|
|
2599
|
-
if (text !== void 0) accumulated += text;
|
|
2600
|
-
buffered.push(event);
|
|
2601
|
-
step = await inner.next();
|
|
2602
|
-
}
|
|
2603
|
-
await runOutputGuards(accumulated, guards);
|
|
2604
|
-
for (const event of buffered) yield event;
|
|
2605
|
-
return step.value;
|
|
2606
|
-
}
|
|
2607
|
-
__name(moderateOutputStream, "moderateOutputStream");
|
|
2608
|
-
|
|
2609
2743
|
// src/loop/compaction-strategy.ts
|
|
2610
2744
|
import { compactTranscript } from "@theokit/sdk/compaction";
|
|
2611
2745
|
import { z } from "zod";
|
|
@@ -3415,13 +3549,13 @@ __name(mcpToolApprovals, "mcpToolApprovals");
|
|
|
3415
3549
|
import { existsSync, readFileSync } from "fs";
|
|
3416
3550
|
import { join } from "path";
|
|
3417
3551
|
import { TheokitAgentError } from "@theokit/sdk/errors";
|
|
3418
|
-
function
|
|
3419
|
-
return opts.onWarn ?? ((
|
|
3420
|
-
process.stderr.write(`[@theokit/agents] ${
|
|
3552
|
+
function warningChannel(opts) {
|
|
3553
|
+
return opts.onWarn ?? ((warning) => {
|
|
3554
|
+
process.stderr.write(`[@theokit/agents] ${warning}
|
|
3421
3555
|
`);
|
|
3422
3556
|
});
|
|
3423
3557
|
}
|
|
3424
|
-
__name(
|
|
3558
|
+
__name(warningChannel, "warningChannel");
|
|
3425
3559
|
var McpFileError = class extends TheokitAgentError {
|
|
3426
3560
|
static {
|
|
3427
3561
|
__name(this, "McpFileError");
|
|
@@ -3447,7 +3581,7 @@ function loadMcpJson(cwd, opts = {}) {
|
|
|
3447
3581
|
} catch (err) {
|
|
3448
3582
|
throw new McpFileError(`${path} is not valid JSON: ${descrever(err)}`);
|
|
3449
3583
|
}
|
|
3450
|
-
return parseMcpJson(parsed, path,
|
|
3584
|
+
return parseMcpJson(parsed, path, warningChannel(opts));
|
|
3451
3585
|
}
|
|
3452
3586
|
__name(loadMcpJson, "loadMcpJson");
|
|
3453
3587
|
function parseMcpJson(raw, source, onWarn) {
|
|
@@ -3466,7 +3600,7 @@ function parseMcpJson(raw, source, onWarn) {
|
|
|
3466
3600
|
onWarn(`${source}: server "${name}" ignorado \u2014 ${motivo}`);
|
|
3467
3601
|
continue;
|
|
3468
3602
|
}
|
|
3469
|
-
out[name] =
|
|
3603
|
+
out[name] = buildEntry(entryRaw);
|
|
3470
3604
|
}
|
|
3471
3605
|
return out;
|
|
3472
3606
|
}
|
|
@@ -3514,16 +3648,16 @@ function validarRemoto(entry) {
|
|
|
3514
3648
|
return void 0;
|
|
3515
3649
|
}
|
|
3516
3650
|
__name(validarRemoto, "validarRemoto");
|
|
3517
|
-
function
|
|
3651
|
+
function buildEntry(entry) {
|
|
3518
3652
|
if (entry.url !== void 0) {
|
|
3519
|
-
const
|
|
3653
|
+
const remote = {
|
|
3520
3654
|
url: entry.url
|
|
3521
3655
|
};
|
|
3522
|
-
if (entry.type !== void 0)
|
|
3523
|
-
if (entry.headers !== void 0)
|
|
3524
|
-
if (entry.auth !== void 0)
|
|
3525
|
-
if (entry.requestTimeoutMs !== void 0)
|
|
3526
|
-
return
|
|
3656
|
+
if (entry.type !== void 0) remote.type = entry.type;
|
|
3657
|
+
if (entry.headers !== void 0) remote.headers = entry.headers;
|
|
3658
|
+
if (entry.auth !== void 0) remote.auth = entry.auth;
|
|
3659
|
+
if (entry.requestTimeoutMs !== void 0) remote.requestTimeoutMs = entry.requestTimeoutMs;
|
|
3660
|
+
return remote;
|
|
3527
3661
|
}
|
|
3528
3662
|
const stdio = {
|
|
3529
3663
|
command: entry.command
|
|
@@ -3533,7 +3667,7 @@ function montarEntrada(entry) {
|
|
|
3533
3667
|
if (entry.cwd !== void 0) stdio.cwd = entry.cwd;
|
|
3534
3668
|
return stdio;
|
|
3535
3669
|
}
|
|
3536
|
-
__name(
|
|
3670
|
+
__name(buildEntry, "buildEntry");
|
|
3537
3671
|
function descrever(err) {
|
|
3538
3672
|
return err instanceof Error ? err.message : String(err);
|
|
3539
3673
|
}
|
|
@@ -3704,10 +3838,21 @@ export {
|
|
|
3704
3838
|
isError,
|
|
3705
3839
|
isApprovalRequired,
|
|
3706
3840
|
generateAgentRoutes,
|
|
3841
|
+
GuardrailViolationError,
|
|
3842
|
+
CostBudgetExceededError,
|
|
3843
|
+
estimateTokens,
|
|
3844
|
+
promptInjectionDetector,
|
|
3845
|
+
piiDetector,
|
|
3846
|
+
unicodeNormalizer,
|
|
3847
|
+
costGuard,
|
|
3848
|
+
outputModeration,
|
|
3849
|
+
runInputGuards,
|
|
3850
|
+
runOutputGuards,
|
|
3851
|
+
moderateOutputStream,
|
|
3707
3852
|
createToolHooksPlugin,
|
|
3708
|
-
translateSdkEvent,
|
|
3709
3853
|
buildModelSelection,
|
|
3710
3854
|
reasoningEffortOf,
|
|
3855
|
+
translateSdkEvent,
|
|
3711
3856
|
createThinkTagExtractor,
|
|
3712
3857
|
extractThinkTagStream,
|
|
3713
3858
|
createSdkAgentStream,
|
|
@@ -3718,17 +3863,6 @@ export {
|
|
|
3718
3863
|
AgentDefinitionError,
|
|
3719
3864
|
compileAgentModule,
|
|
3720
3865
|
streamAgentUIMessages,
|
|
3721
|
-
GuardrailViolationError,
|
|
3722
|
-
CostBudgetExceededError,
|
|
3723
|
-
estimateTokens,
|
|
3724
|
-
promptInjectionDetector,
|
|
3725
|
-
piiDetector,
|
|
3726
|
-
unicodeNormalizer,
|
|
3727
|
-
costGuard,
|
|
3728
|
-
outputModeration,
|
|
3729
|
-
runInputGuards,
|
|
3730
|
-
runOutputGuards,
|
|
3731
|
-
moderateOutputStream,
|
|
3732
3866
|
DEFAULT_KEEP_TOKENS,
|
|
3733
3867
|
compactionStrategyConfigSchema,
|
|
3734
3868
|
resolveCompactionStrategy,
|
|
@@ -3759,4 +3893,4 @@ export {
|
|
|
3759
3893
|
generateAgentManifest,
|
|
3760
3894
|
agentsPlugin
|
|
3761
3895
|
};
|
|
3762
|
-
//# sourceMappingURL=chunk-
|
|
3896
|
+
//# sourceMappingURL=chunk-3YPKTOJ6.js.map
|