@fased/fased 0.1.57 → 0.1.59
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/agents/anthropic-payload-policy.js +188 -0
- package/dist/agents/anthropic-transport-stream.js +736 -0
- package/dist/agents/copilot-dynamic-headers.js +1 -1
- package/dist/agents/current-model-catalog.js +5 -2
- package/dist/agents/custom-api-registry.js +21 -0
- package/dist/agents/google-transport-stream.js +543 -0
- package/dist/agents/model-catalog-status.js +6 -1
- package/dist/agents/models-config.js +2 -1
- package/dist/agents/openai-completions-compat.js +49 -0
- package/dist/agents/openai-responses-payload-policy.js +100 -0
- package/dist/agents/openai-tool-schema.js +130 -0
- package/dist/agents/openai-transport-stream.js +1040 -0
- package/dist/agents/pi-embedded-runner/compact.js +9 -0
- package/dist/agents/pi-embedded-runner/run/attempt.js +9 -0
- package/dist/agents/pi-embedded-runner/session-manager-init.js +5 -20
- package/dist/agents/provider-extension-catalog-manifest.js +2 -2
- package/dist/agents/provider-request-config.js +1 -1
- package/dist/agents/provider-stream.js +29 -0
- package/dist/agents/provider-transport-fetch.js +89 -0
- package/dist/agents/provider-transport-stream.js +72 -0
- package/dist/agents/system-prompt-cache-boundary.js +1 -1
- package/dist/agents/system-prompt.js +1 -1
- package/dist/agents/transport-message-transform.js +143 -0
- package/dist/agents/transport-stream-shared.js +81 -0
- package/dist/brand.js +1 -1
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/channels/delivery.js +78 -0
- package/dist/channels/plugins/catalog.js +10 -5
- package/dist/cli/components-cli.js +16 -13
- package/dist/cli/program/register.subclis.js +9 -0
- package/dist/cli/providers-cli.js +79 -6
- package/dist/cli/services-cli.js +28 -0
- package/dist/commands/auth-choice.js +1 -1
- package/dist/commands/models/list.auth-overview.js +12 -0
- package/dist/commands/onboard-channels.js +5 -0
- package/dist/commands/onboard-helpers.js +1 -1
- package/dist/commands/vllm-setup.js +12 -3
- package/dist/control-ui/assets/{app-DltSyY4Y.js → app-S_jg-ADS.js} +1706 -1675
- package/dist/control-ui/assets/{index-D5JlBp7f.js → index-C22rDOFm.js} +3 -3
- package/dist/control-ui/assets/{providers-Cc89iMdx.js → providers-QMn4w2_f.js} +3 -3
- package/dist/control-ui/index.html +1 -1
- package/dist/control-ui/version.json +1 -1
- package/dist/gateway/control-reply-text.js +10 -1
- package/dist/gateway/method-scopes.js +2 -0
- package/dist/gateway/protocol/schema/agents-models-skills.js +1 -0
- package/dist/gateway/server-chat.js +3 -3
- package/dist/gateway/server-methods/channels.js +10 -2
- package/dist/gateway/server-methods/chat.js +19 -12
- package/dist/gateway/server-methods/models.js +4 -0
- package/dist/gateway/server-methods/services.js +47 -2
- package/dist/gateway/server-methods-list.js +2 -0
- package/dist/gateway/session-event-payloads.js +20 -9
- package/dist/infra/google-api-base-url.js +29 -0
- package/dist/plugin-sdk/{accounts-CmMwe9Dt.js → accounts-DxblobYM.js} +1 -1
- package/dist/plugin-sdk/{actions-DYViFQiX.js → actions-D4UNimWa.js} +2 -2
- package/dist/plugin-sdk/{active-listener-DVbpcisf.js → active-listener-CFuy106s.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-D-Mfay8i.js → audio-preflight-CxZixyhW.js} +25 -25
- package/dist/plugin-sdk/{audit-JImYFOzJ.js → audit-Cs0K7LBp.js} +1 -1
- package/dist/plugin-sdk/{channel-access-cxCK2mci.js → channel-access-D5aHoTY8.js} +1 -1
- package/dist/plugin-sdk/{channel-access-configure-B_qYjml8.js → channel-access-configure-Dvch9mMQ.js} +1 -1
- package/dist/plugin-sdk/channel-plugin-common.d.ts +2 -2
- package/dist/plugin-sdk/channel-plugin-common.js +4 -4
- package/dist/plugin-sdk/{chunk-CF8nvZNj.js → chunk-B0FUGc5A.js} +1 -1
- package/dist/plugin-sdk/{chunk-items-yLFoO571.js → chunk-items-Cy9a3X7x.js} +1 -1
- package/dist/plugin-sdk/command-status.js +25 -25
- package/dist/plugin-sdk/{commands-registry-CK4KmMG0.js → commands-registry-DmDRhRAU.js} +2 -2
- package/dist/plugin-sdk/{common-Cky4hpqr.js → common-CfUOowOp.js} +1 -1
- package/dist/plugin-sdk/{config-Dbxj_jUP.js → config-mxULv0fQ.js} +4 -1
- package/dist/plugin-sdk/{config-schema-aKPMn6ML.js → config-schema-D8E0LX8X.js} +4422 -486
- package/dist/plugin-sdk/device-pair.d.ts +1 -1
- package/dist/plugin-sdk/discord.d.ts +4 -4
- package/dist/plugin-sdk/discord.js +19 -19
- package/dist/plugin-sdk/{handle-action-BSNDD2Vc.js → handle-action-DbVCF9HZ.js} +13 -13
- package/dist/plugin-sdk/{helpers-CDo2XBSr.js → helpers-BXbdgs5H.js} +1 -1
- package/dist/plugin-sdk/{image-ops-DbeBxbn4.js → image-ops-D7jPxaph.js} +1 -1
- package/dist/plugin-sdk/index.d.ts +15 -15
- package/dist/plugin-sdk/index.js +27 -27
- package/dist/plugin-sdk/{login-CWXvFTd8.js → login-BRxww6nv.js} +3 -3
- package/dist/plugin-sdk/{login-qr-CJB2zjmM.js → login-qr-DJXsk9XH.js} +3 -3
- package/dist/plugin-sdk/{manager-CbiFFLKS.js → manager-Y2S_5IlI.js} +2 -2
- package/dist/plugin-sdk/{markdown-tables-Bskt9r8i.js → markdown-tables-DHLFQqaF.js} +1 -1
- package/dist/plugin-sdk/{media-B3aAg5rh.js → media-Czo4carg.js} +2 -2
- package/dist/plugin-sdk/{monitor-BYGbTI5V.js → monitor-CFHFAUOj.js} +32 -32
- package/dist/plugin-sdk/{monitor-BJs6z7AT.js → monitor-xS9A8Upr.js} +29 -29
- package/dist/plugin-sdk/ollama-runtime.js +970 -0
- package/dist/plugin-sdk/{openresponses-http-BGCl2dS2.js → openresponses-http-BcUbeVV6.js} +25 -25
- package/dist/plugin-sdk/{optional-runtime-dependency-BlTVkcAg.js → optional-runtime-dependency-DdMbxS24.js} +1 -1
- package/dist/plugin-sdk/{outbound-CIemga5_.js → outbound-Db8mRN6P.js} +6 -6
- package/dist/plugin-sdk/{outbound-attachment-2RckWqrk.js → outbound-attachment-BqFjcypb.js} +2 -2
- package/dist/plugin-sdk/{pairing-message-r-VQfhFB.js → pairing-message-B3GC_7CD.js} +1 -1
- package/dist/plugin-sdk/{pairing-message-C403mq4K.d.ts → pairing-message-CxonJmwM.d.ts} +1 -1
- package/dist/plugin-sdk/{pairing-store-uPnLfGgB.js → pairing-store-CQikgIbw.js} +2 -2
- package/dist/plugin-sdk/{pi-model-discovery-BpEilAym.js → pi-model-discovery-CY3m5zJP.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-DwNdFaz-.js → pi-model-discovery-runtime-DSh1T2pn.js} +2 -2
- package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +1 -1
- package/dist/plugin-sdk/{pw-ai-H7UgunQQ.js → pw-ai-AFUqn-tQ.js} +3 -3
- package/dist/plugin-sdk/{replies-CKMwkH4G.js → replies-Fzh9PhXl.js} +2 -2
- package/dist/plugin-sdk/{resolve-outbound-target-B68fSoGi.js → resolve-outbound-target-KpF3co6T.js} +1 -1
- package/dist/plugin-sdk/{resolve-route-B8fOfihG.js → resolve-route-CDl74O19.js} +1 -1
- package/dist/plugin-sdk/{retry-policy-B6GQldxB.js → retry-policy-D4uiqUOG.js} +1 -1
- package/dist/plugin-sdk/{runtime-nVJl3PlS.js → runtime-Bb6KRnCC.js} +6 -4
- package/dist/plugin-sdk/{runtime-dependency-DlqVSsSs.js → runtime-dependency-DLDmB94f.js} +11 -11
- package/dist/plugin-sdk/sat-runtime.d.ts +2 -2
- package/dist/plugin-sdk/sat-runtime.js +25 -25
- package/dist/plugin-sdk/{send-CPK_HlYW.js → send-5nFktR1n.js} +5 -5
- package/dist/plugin-sdk/{send-hSu1HWms.js → send-Bfzf11VY.js} +7 -7
- package/dist/plugin-sdk/{send-D3DQOg2a.js → send-C4k4JuJN.js} +6 -6
- package/dist/plugin-sdk/{send-BHokB4TR.js → send-D-uDKGIq.js} +6 -6
- package/dist/plugin-sdk/{send-BCJ4hi3t.js → send-Du8ykP1k.js} +8 -8
- package/dist/plugin-sdk/{session-DQ4Dr-mf.js → session-CS-Td9EM.js} +2 -2
- package/dist/plugin-sdk/{skill-commands-CmdoKLh_.js → skill-commands-CFAlXWHk.js} +2 -2
- package/dist/plugin-sdk/{slack-B70NHpMF.js → slack-DXYGbizH.js} +37 -37
- package/dist/plugin-sdk/{slack-actions-fSmP981b.js → slack-actions-BcMkNv1Z.js} +11 -11
- package/dist/plugin-sdk/slack.d.ts +4 -4
- package/dist/plugin-sdk/slack.js +9 -9
- package/dist/plugin-sdk/{sticker-cache-B4dG2sKU.js → sticker-cache-Dr3rYfU1.js} +3 -3
- package/dist/plugin-sdk/{tables-EX4Hy-a-.js → tables-bFXyRpkx.js} +1 -1
- package/dist/plugin-sdk/{targets-BeGUCGWK.js → targets-DH7a9lKB.js} +1 -1
- package/dist/plugin-sdk/{telegram-actions-CM8SJgc9.js → telegram-actions-Besbw_Hg.js} +28 -28
- package/dist/plugin-sdk/telegram.d.ts +4 -4
- package/dist/plugin-sdk/telegram.js +8 -8
- package/dist/plugin-sdk/{thread-bindings.lifecycle-tHK_1mvp.js → thread-bindings.lifecycle-CgOvvdw8.js} +3 -3
- package/dist/plugin-sdk/{thread-bindings.state-D7xG1GHu.js → thread-bindings.state-CQpk44Hq.js} +2 -2
- package/dist/plugin-sdk/{tmp-fased-dir-Ouj58axY.d.ts → tmp-fased-dir-DQ00xQ5D.d.ts} +1 -1
- package/dist/plugin-sdk/{types-B4hj6HgR.d.ts → types-B6zx-Dl2.d.ts} +1 -1
- package/dist/plugin-sdk/{types-dWZFX1fk.d.ts → types-eUM7hcDz.d.ts} +1 -1
- package/dist/plugin-sdk/{web-BFolfZ3i.js → web-Q1-G--JH.js} +30 -30
- package/dist/plugin-sdk/{whatsapp-actions-CYmleHCz.js → whatsapp-actions-BtSc2CBv.js} +13 -13
- package/dist/plugin-sdk/{whatsapp-heartbeat-BEwm4GK3.js → whatsapp-heartbeat-Bg9TuYzl.js} +2 -2
- package/dist/plugin-sdk/whatsapp.d.ts +9 -9
- package/dist/plugin-sdk/whatsapp.js +12 -12
- package/dist/plugin-sdk/{wsl-BtMDzMv5.js → wsl-C4DGFkOd.js} +3 -3
- package/dist/plugin-sdk/{zod-schema.providers-core-FaYR6KdD.d.ts → zod-schema.providers-core-CIzCjXH9.d.ts} +61 -61
- package/dist/plugins/provider-runtime.js +79 -0
- package/dist/providers/refresh.js +14 -0
- package/extensions/acpx/package.json +1 -1
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/fased-federation/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +12 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +2 -2
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +12 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +12 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/sat-mining/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/synology-chat/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +12 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +12 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +12 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +12 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
|
@@ -30,6 +30,7 @@ import { resolveFasedAgentDocsPath } from "../docs-path.js";
|
|
|
30
30
|
import { createPreparedEmbeddedPiSettingsManager } from "../pi-project-settings.js";
|
|
31
31
|
import { detectRuntimeShell } from "../shell-utils.js";
|
|
32
32
|
import { createFasedAgentCodingTools } from "../pi-tools.js";
|
|
33
|
+
import { registerProviderStreamForModel } from "../provider-stream.js";
|
|
33
34
|
import { repairSessionFileIfNeeded } from "../session-file-repair.js";
|
|
34
35
|
import { log } from "./logger.js";
|
|
35
36
|
import { sanitizeToolUseResultPairing } from "../session-transcript-repair.js";
|
|
@@ -436,6 +437,14 @@ async function compactEmbeddedPiSessionDirect(params) {
|
|
|
436
437
|
tools,
|
|
437
438
|
sandboxEnabled: !!sandbox?.enabled
|
|
438
439
|
});
|
|
440
|
+
if (model.api === "ollama") {
|
|
441
|
+
registerProviderStreamForModel({
|
|
442
|
+
model,
|
|
443
|
+
cfg: params.config,
|
|
444
|
+
agentDir,
|
|
445
|
+
workspaceDir: params.workspaceDir
|
|
446
|
+
});
|
|
447
|
+
}
|
|
439
448
|
const { session } = await createAgentSession({
|
|
440
449
|
cwd: resolvedWorkspace,
|
|
441
450
|
agentDir,
|
|
@@ -33,6 +33,7 @@ import { isTimeoutError } from "../../failover-error.js";
|
|
|
33
33
|
import { resolveSandboxRuntimeStatus } from "../../sandbox/runtime-status.js";
|
|
34
34
|
import { resolveEffectiveToolFsWorkspaceOnly } from "../../tool-fs-policy.js";
|
|
35
35
|
import { createFasedAgentCodingTools, filterToolsByDisabledToolNames, resolveToolLoopDetectionConfig } from "../../pi-tools.js";
|
|
36
|
+
import { registerProviderStreamForModel } from "../../provider-stream.js";
|
|
36
37
|
import { repairSessionFileIfNeeded } from "../../session-file-repair.js";
|
|
37
38
|
import { log } from "../logger.js";
|
|
38
39
|
import { sanitizeToolCallIdsForCloudCodeAssist } from "../../tool-call-id.js";
|
|
@@ -580,6 +581,14 @@ async function runEmbeddedAttempt(params) {
|
|
|
580
581
|
loopDetection: clientToolLoopDetection
|
|
581
582
|
}) : [];
|
|
582
583
|
const allCustomTools = [...customTools, ...clientToolDefs];
|
|
584
|
+
if (params.model.api === "ollama") {
|
|
585
|
+
registerProviderStreamForModel({
|
|
586
|
+
model: params.model,
|
|
587
|
+
cfg: params.config,
|
|
588
|
+
agentDir,
|
|
589
|
+
workspaceDir: params.workspaceDir
|
|
590
|
+
});
|
|
591
|
+
}
|
|
583
592
|
({session} = await createAgentSession({
|
|
584
593
|
cwd: resolvedWorkspace,
|
|
585
594
|
agentDir,
|
|
@@ -1,33 +1,18 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
|
|
3
1
|
//#region src/agents/pi-embedded-runner/session-manager-init.ts
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* This normalizes the file/session state so the first user prompt is persisted before the first
|
|
12
|
-
* assistant entry, even for pre-created session files.
|
|
3
|
+
* Keep Fased's requested identity for new transcripts while leaving existing
|
|
4
|
+
* transcripts under SessionManager's append lifecycle. In particular, an
|
|
5
|
+
* existing header-only file is already marked flushed by SessionManager and
|
|
6
|
+
* must not be truncated or reset to unflushed: its next assistant write uses
|
|
7
|
+
* exclusive creation and would fail with EEXIST.
|
|
13
8
|
*/
|
|
14
9
|
async function prepareSessionManagerForRun(params) {
|
|
15
10
|
const sm = params.sessionManager;
|
|
16
11
|
const header = sm.fileEntries.find((e) => e.type === "session");
|
|
17
|
-
const hasAssistant = sm.fileEntries.some((e) => e.type === "message" && e.message?.role === "assistant");
|
|
18
12
|
if (!params.hadSessionFile && header) {
|
|
19
13
|
header.id = params.sessionId;
|
|
20
14
|
header.cwd = params.cwd;
|
|
21
15
|
sm.sessionId = params.sessionId;
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
if (params.hadSessionFile && header && !hasAssistant) {
|
|
25
|
-
await fs.writeFile(params.sessionFile, "", "utf-8");
|
|
26
|
-
sm.fileEntries = [header];
|
|
27
|
-
sm.byId?.clear?.();
|
|
28
|
-
sm.labelsById?.clear?.();
|
|
29
|
-
sm.leafId = null;
|
|
30
|
-
sm.flushed = false;
|
|
31
16
|
}
|
|
32
17
|
}
|
|
33
18
|
|
|
@@ -56,8 +56,8 @@ const FASED_PROVIDER_EXTENSION_CATALOG_MANIFEST = [
|
|
|
56
56
|
upstreamProviderId: "kimi-coding",
|
|
57
57
|
upstreamCatalogPaths: ["extensions/kimi-coding/provider-catalog.ts"],
|
|
58
58
|
status: "mapped",
|
|
59
|
-
fasedProviderIds: ["kimi"],
|
|
60
|
-
fasedProviderAliases: ["kimi
|
|
59
|
+
fasedProviderIds: ["kimi-coding"],
|
|
60
|
+
fasedProviderAliases: ["kimi", "kimi-code"],
|
|
61
61
|
docsPath: "docs/providers/moonshot.md",
|
|
62
62
|
authSurface: "api-key",
|
|
63
63
|
authChoiceIds: ["kimi-code-api-key"]
|
|
@@ -460,4 +460,4 @@ function getModelProviderRequestTransport(model) {
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
//#endregion
|
|
463
|
-
export { attachModelProviderRequestTransport, sanitizeConfiguredModelProviderRequest };
|
|
463
|
+
export { attachModelProviderRequestTransport, buildProviderRequestDispatcherPolicy, getModelProviderRequestTransport, resolveProviderRequestPolicyConfig, sanitizeConfiguredModelProviderRequest };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { resolveProviderStreamFn } from "../plugins/provider-runtime.js";
|
|
2
|
+
import { ensureCustomApiRegistered } from "./custom-api-registry.js";
|
|
3
|
+
import { createTransportAwareStreamFnForModel } from "./provider-transport-stream.js";
|
|
4
|
+
|
|
5
|
+
//#region src/agents/provider-stream.ts
|
|
6
|
+
function registerProviderStreamForModel(params) {
|
|
7
|
+
const streamFn = resolveProviderStreamFn({
|
|
8
|
+
provider: params.model.provider,
|
|
9
|
+
config: params.cfg,
|
|
10
|
+
workspaceDir: params.workspaceDir,
|
|
11
|
+
env: params.env,
|
|
12
|
+
context: {
|
|
13
|
+
config: params.cfg,
|
|
14
|
+
agentDir: params.agentDir,
|
|
15
|
+
workspaceDir: params.workspaceDir,
|
|
16
|
+
provider: params.model.provider,
|
|
17
|
+
modelId: params.model.id,
|
|
18
|
+
model: params.model
|
|
19
|
+
}
|
|
20
|
+
}) ?? createTransportAwareStreamFnForModel(params.model);
|
|
21
|
+
if (!streamFn) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
ensureCustomApiRegistered(params.model.api, streamFn);
|
|
25
|
+
return streamFn;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { registerProviderStreamForModel };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js";
|
|
2
|
+
import { buildProviderRequestDispatcherPolicy, getModelProviderRequestTransport, resolveProviderRequestPolicyConfig } from "./provider-request-config.js";
|
|
3
|
+
|
|
4
|
+
//#region src/agents/provider-transport-fetch.ts
|
|
5
|
+
function buildManagedResponse(response, release) {
|
|
6
|
+
if (!response.body) {
|
|
7
|
+
void release();
|
|
8
|
+
return response;
|
|
9
|
+
}
|
|
10
|
+
const source = response.body;
|
|
11
|
+
let reader;
|
|
12
|
+
let released = false;
|
|
13
|
+
const finalize = async () => {
|
|
14
|
+
if (released) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
released = true;
|
|
18
|
+
await release().catch(() => undefined);
|
|
19
|
+
};
|
|
20
|
+
const wrappedBody = new ReadableStream({
|
|
21
|
+
start() {
|
|
22
|
+
reader = source.getReader();
|
|
23
|
+
},
|
|
24
|
+
async pull(controller) {
|
|
25
|
+
try {
|
|
26
|
+
const chunk = await reader?.read();
|
|
27
|
+
if (!chunk || chunk.done) {
|
|
28
|
+
controller.close();
|
|
29
|
+
await finalize();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
controller.enqueue(chunk.value);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
controller.error(error);
|
|
35
|
+
await finalize();
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
async cancel(reason) {
|
|
39
|
+
try {
|
|
40
|
+
await reader?.cancel(reason);
|
|
41
|
+
} finally {
|
|
42
|
+
await finalize();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return new Response(wrappedBody, {
|
|
47
|
+
status: response.status,
|
|
48
|
+
statusText: response.statusText,
|
|
49
|
+
headers: response.headers
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function resolveModelRequestPolicy(model) {
|
|
53
|
+
return resolveProviderRequestPolicyConfig({
|
|
54
|
+
provider: model.provider,
|
|
55
|
+
api: model.api,
|
|
56
|
+
baseUrl: model.baseUrl,
|
|
57
|
+
capability: "llm",
|
|
58
|
+
transport: "stream",
|
|
59
|
+
request: getModelProviderRequestTransport(model)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function buildGuardedModelFetch(model) {
|
|
63
|
+
const requestConfig = resolveModelRequestPolicy(model);
|
|
64
|
+
const dispatcherPolicy = buildProviderRequestDispatcherPolicy(requestConfig);
|
|
65
|
+
return async (input, init) => {
|
|
66
|
+
const request = input instanceof Request ? new Request(input, init) : undefined;
|
|
67
|
+
const url = request?.url ?? (input instanceof URL ? input.toString() : typeof input === "string" ? input : (() => {
|
|
68
|
+
throw new Error("Unsupported fetch input for transport-aware model request");
|
|
69
|
+
})());
|
|
70
|
+
const requestInit = request && {
|
|
71
|
+
method: request.method,
|
|
72
|
+
headers: request.headers,
|
|
73
|
+
body: request.body ?? undefined,
|
|
74
|
+
redirect: request.redirect,
|
|
75
|
+
signal: request.signal,
|
|
76
|
+
...request.body ? { duplex: "half" } : {}
|
|
77
|
+
};
|
|
78
|
+
const result = await fetchWithSsrFGuard({
|
|
79
|
+
url,
|
|
80
|
+
init: requestInit ?? init,
|
|
81
|
+
dispatcherPolicy,
|
|
82
|
+
...requestConfig.allowPrivateNetwork ? { policy: { allowPrivateNetwork: true } } : {}
|
|
83
|
+
});
|
|
84
|
+
return buildManagedResponse(result.response, result.release);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { buildGuardedModelFetch };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { getModelProviderRequestTransport } from "./provider-request-config.js";
|
|
2
|
+
import { createAnthropicMessagesTransportStreamFn } from "./anthropic-transport-stream.js";
|
|
3
|
+
import { createGoogleGenerativeAiTransportStreamFn } from "./google-transport-stream.js";
|
|
4
|
+
import { createOpenAICompletionsTransportStreamFn, createOpenAIResponsesTransportStreamFn } from "./openai-transport-stream.js";
|
|
5
|
+
|
|
6
|
+
//#region src/agents/provider-transport-stream.ts
|
|
7
|
+
const SUPPORTED_TRANSPORT_APIS = new Set([
|
|
8
|
+
"openai-responses",
|
|
9
|
+
"openai-codex-responses",
|
|
10
|
+
"openai-completions",
|
|
11
|
+
"anthropic-messages",
|
|
12
|
+
"google-generative-ai"
|
|
13
|
+
]);
|
|
14
|
+
const SIMPLE_TRANSPORT_API_ALIAS = {
|
|
15
|
+
"openai-responses": "fased-openai-responses-transport",
|
|
16
|
+
"openai-codex-responses": "fased-openai-responses-transport",
|
|
17
|
+
"openai-completions": "fased-openai-completions-transport",
|
|
18
|
+
"anthropic-messages": "fased-anthropic-messages-transport",
|
|
19
|
+
"google-generative-ai": "fased-google-generative-ai-transport"
|
|
20
|
+
};
|
|
21
|
+
function createSupportedTransportStreamFn(api) {
|
|
22
|
+
switch (api) {
|
|
23
|
+
case "openai-responses":
|
|
24
|
+
case "openai-codex-responses": return createOpenAIResponsesTransportStreamFn();
|
|
25
|
+
case "openai-completions": return createOpenAICompletionsTransportStreamFn();
|
|
26
|
+
case "anthropic-messages": return createAnthropicMessagesTransportStreamFn();
|
|
27
|
+
case "google-generative-ai": return createGoogleGenerativeAiTransportStreamFn();
|
|
28
|
+
default: return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function hasTransportOverrides(model) {
|
|
32
|
+
const request = getModelProviderRequestTransport(model);
|
|
33
|
+
return Boolean(request?.proxy || request?.tls || request?.allowPrivateNetwork !== undefined);
|
|
34
|
+
}
|
|
35
|
+
function isTransportAwareApiSupported(api) {
|
|
36
|
+
return SUPPORTED_TRANSPORT_APIS.has(api);
|
|
37
|
+
}
|
|
38
|
+
function resolveTransportAwareSimpleApi(api) {
|
|
39
|
+
return SIMPLE_TRANSPORT_API_ALIAS[api];
|
|
40
|
+
}
|
|
41
|
+
function createTransportAwareStreamFnForModel(model) {
|
|
42
|
+
if (!hasTransportOverrides(model)) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
if (!isTransportAwareApiSupported(model.api)) {
|
|
46
|
+
throw new Error(`Model-provider request controls are not yet supported for api "${model.api}"`);
|
|
47
|
+
}
|
|
48
|
+
return createSupportedTransportStreamFn(model.api);
|
|
49
|
+
}
|
|
50
|
+
function createBoundaryAwareStreamFnForModel(model) {
|
|
51
|
+
if (!isTransportAwareApiSupported(model.api)) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
return createSupportedTransportStreamFn(model.api);
|
|
55
|
+
}
|
|
56
|
+
function prepareTransportAwareSimpleModel(model) {
|
|
57
|
+
const streamFn = createTransportAwareStreamFnForModel(model);
|
|
58
|
+
const alias = resolveTransportAwareSimpleApi(model.api);
|
|
59
|
+
if (!streamFn || !alias) {
|
|
60
|
+
return model;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
...model,
|
|
64
|
+
api: alias
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function buildTransportAwareSimpleStreamFn(model) {
|
|
68
|
+
return createTransportAwareStreamFnForModel(model);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
export { createTransportAwareStreamFnForModel };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { listDeliverableMessageChannels } from "../utils/message-channel.js";
|
|
2
2
|
import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
|
3
3
|
import { normalizePromptCapabilityIds, normalizeStructuredPromptSection } from "./prompt-cache-stability.js";
|
|
4
|
-
import { sanitizeForPromptLiteral } from "./sanitize-for-prompt.js";
|
|
5
4
|
import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "./system-prompt-cache-boundary.js";
|
|
5
|
+
import { sanitizeForPromptLiteral } from "./sanitize-for-prompt.js";
|
|
6
6
|
import { createHash, createHmac } from "node:crypto";
|
|
7
7
|
|
|
8
8
|
//#region src/agents/system-prompt.ts
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
//#region src/agents/transport-message-transform.ts
|
|
2
|
+
function transformTransportMessages(messages, model, normalizeToolCallId) {
|
|
3
|
+
const toolCallIdMap = new Map();
|
|
4
|
+
const transformed = messages.map((msg) => {
|
|
5
|
+
if (msg.role === "user") {
|
|
6
|
+
return msg;
|
|
7
|
+
}
|
|
8
|
+
if (msg.role === "toolResult") {
|
|
9
|
+
const normalizedId = toolCallIdMap.get(msg.toolCallId);
|
|
10
|
+
return normalizedId && normalizedId !== msg.toolCallId ? {
|
|
11
|
+
...msg,
|
|
12
|
+
toolCallId: normalizedId
|
|
13
|
+
} : msg;
|
|
14
|
+
}
|
|
15
|
+
if (msg.role !== "assistant") {
|
|
16
|
+
return msg;
|
|
17
|
+
}
|
|
18
|
+
const isSameModel = msg.provider === model.provider && msg.api === model.api && msg.model === model.id;
|
|
19
|
+
const content = [];
|
|
20
|
+
for (const block of msg.content) {
|
|
21
|
+
if (block.type === "thinking") {
|
|
22
|
+
const thinkingBlock = block;
|
|
23
|
+
if (thinkingBlock.redacted) {
|
|
24
|
+
if (isSameModel) {
|
|
25
|
+
content.push(thinkingBlock);
|
|
26
|
+
}
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (isSameModel && block.thinkingSignature) {
|
|
30
|
+
content.push(block);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!block.thinking.trim()) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
content.push(isSameModel ? block : {
|
|
37
|
+
type: "text",
|
|
38
|
+
text: block.thinking
|
|
39
|
+
});
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (block.type === "text") {
|
|
43
|
+
content.push(isSameModel ? block : {
|
|
44
|
+
type: "text",
|
|
45
|
+
text: block.text
|
|
46
|
+
});
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (block.type !== "toolCall") {
|
|
50
|
+
content.push(block);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
let normalizedToolCall = block;
|
|
54
|
+
if (!isSameModel && block.thoughtSignature) {
|
|
55
|
+
normalizedToolCall = { ...normalizedToolCall };
|
|
56
|
+
delete normalizedToolCall.thoughtSignature;
|
|
57
|
+
}
|
|
58
|
+
if (!isSameModel && normalizeToolCallId) {
|
|
59
|
+
const normalizedId = normalizeToolCallId(block.id, model, msg);
|
|
60
|
+
if (normalizedId !== block.id) {
|
|
61
|
+
toolCallIdMap.set(block.id, normalizedId);
|
|
62
|
+
normalizedToolCall = {
|
|
63
|
+
...normalizedToolCall,
|
|
64
|
+
id: normalizedId
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
content.push(normalizedToolCall);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
...msg,
|
|
72
|
+
content
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
const result = [];
|
|
76
|
+
let pendingToolCalls = [];
|
|
77
|
+
let existingToolResultIds = new Set();
|
|
78
|
+
for (const msg of transformed) {
|
|
79
|
+
if (msg.role === "assistant") {
|
|
80
|
+
if (pendingToolCalls.length > 0) {
|
|
81
|
+
for (const toolCall of pendingToolCalls) {
|
|
82
|
+
if (!existingToolResultIds.has(toolCall.id)) {
|
|
83
|
+
result.push({
|
|
84
|
+
role: "toolResult",
|
|
85
|
+
toolCallId: toolCall.id,
|
|
86
|
+
toolName: toolCall.name,
|
|
87
|
+
content: [{
|
|
88
|
+
type: "text",
|
|
89
|
+
text: "No result provided"
|
|
90
|
+
}],
|
|
91
|
+
isError: true,
|
|
92
|
+
timestamp: Date.now()
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
pendingToolCalls = [];
|
|
97
|
+
existingToolResultIds = new Set();
|
|
98
|
+
}
|
|
99
|
+
if (msg.stopReason === "error" || msg.stopReason === "aborted") {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const toolCalls = msg.content.filter((block) => block.type === "toolCall");
|
|
103
|
+
if (toolCalls.length > 0) {
|
|
104
|
+
pendingToolCalls = toolCalls.map((block) => ({
|
|
105
|
+
id: block.id,
|
|
106
|
+
name: block.name
|
|
107
|
+
}));
|
|
108
|
+
existingToolResultIds = new Set();
|
|
109
|
+
}
|
|
110
|
+
result.push(msg);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (msg.role === "toolResult") {
|
|
114
|
+
existingToolResultIds.add(msg.toolCallId);
|
|
115
|
+
result.push(msg);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (pendingToolCalls.length > 0) {
|
|
119
|
+
for (const toolCall of pendingToolCalls) {
|
|
120
|
+
if (!existingToolResultIds.has(toolCall.id)) {
|
|
121
|
+
result.push({
|
|
122
|
+
role: "toolResult",
|
|
123
|
+
toolCallId: toolCall.id,
|
|
124
|
+
toolName: toolCall.name,
|
|
125
|
+
content: [{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: "No result provided"
|
|
128
|
+
}],
|
|
129
|
+
isError: true,
|
|
130
|
+
timestamp: Date.now()
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
pendingToolCalls = [];
|
|
135
|
+
existingToolResultIds = new Set();
|
|
136
|
+
}
|
|
137
|
+
result.push(msg);
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
export { transformTransportMessages };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createAssistantMessageEventStream } from "@mariozechner/pi-ai/compat";
|
|
2
|
+
|
|
3
|
+
//#region src/agents/transport-stream-shared.ts
|
|
4
|
+
function sanitizeTransportPayloadText(text) {
|
|
5
|
+
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
6
|
+
}
|
|
7
|
+
function mergeTransportHeaders(...headerSources) {
|
|
8
|
+
const merged = {};
|
|
9
|
+
for (const headers of headerSources) {
|
|
10
|
+
if (headers) {
|
|
11
|
+
Object.assign(merged, headers);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
15
|
+
}
|
|
16
|
+
function mergeTransportMetadata(payload, metadata) {
|
|
17
|
+
if (!metadata || Object.keys(metadata).length === 0) {
|
|
18
|
+
return payload;
|
|
19
|
+
}
|
|
20
|
+
const existingMetadata = payload.metadata && typeof payload.metadata === "object" && !Array.isArray(payload.metadata) ? payload.metadata : undefined;
|
|
21
|
+
return {
|
|
22
|
+
...payload,
|
|
23
|
+
metadata: {
|
|
24
|
+
...existingMetadata,
|
|
25
|
+
...metadata
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function createEmptyTransportUsage() {
|
|
30
|
+
return {
|
|
31
|
+
input: 0,
|
|
32
|
+
output: 0,
|
|
33
|
+
cacheRead: 0,
|
|
34
|
+
cacheWrite: 0,
|
|
35
|
+
totalTokens: 0,
|
|
36
|
+
cost: {
|
|
37
|
+
input: 0,
|
|
38
|
+
output: 0,
|
|
39
|
+
cacheRead: 0,
|
|
40
|
+
cacheWrite: 0,
|
|
41
|
+
total: 0
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function createWritableTransportEventStream() {
|
|
46
|
+
const eventStream = createAssistantMessageEventStream();
|
|
47
|
+
return {
|
|
48
|
+
eventStream,
|
|
49
|
+
stream: eventStream
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function finalizeTransportStream(params) {
|
|
53
|
+
const { stream, output, signal } = params;
|
|
54
|
+
if (signal?.aborted) {
|
|
55
|
+
throw new Error("Request was aborted");
|
|
56
|
+
}
|
|
57
|
+
if (output.stopReason === "aborted" || output.stopReason === "error") {
|
|
58
|
+
throw new Error("An unknown error occurred");
|
|
59
|
+
}
|
|
60
|
+
stream.push({
|
|
61
|
+
type: "done",
|
|
62
|
+
reason: output.stopReason,
|
|
63
|
+
message: output
|
|
64
|
+
});
|
|
65
|
+
stream.end();
|
|
66
|
+
}
|
|
67
|
+
function failTransportStream(params) {
|
|
68
|
+
const { stream, output, signal, error, cleanup } = params;
|
|
69
|
+
cleanup?.();
|
|
70
|
+
output.stopReason = signal?.aborted ? "aborted" : "error";
|
|
71
|
+
output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
72
|
+
stream.push({
|
|
73
|
+
type: "error",
|
|
74
|
+
reason: output.stopReason,
|
|
75
|
+
error: output
|
|
76
|
+
});
|
|
77
|
+
stream.end();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
export { createEmptyTransportUsage, createWritableTransportEventStream, failTransportStream, finalizeTransportStream, mergeTransportHeaders, mergeTransportMetadata, sanitizeTransportPayloadText };
|
package/dist/brand.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const FASED_BRAND_NAME = "Fased";
|
|
3
3
|
const FASED_AGENT_NAME = "Fased Agent";
|
|
4
4
|
const FASED_CONTROL_NAME = "Fased Control";
|
|
5
|
-
const FASED_PRODUCT_VERSION = "0.1.
|
|
5
|
+
const FASED_PRODUCT_VERSION = "0.1.59";
|
|
6
6
|
const FASED_DISPLAY_VERSION = `v${FASED_PRODUCT_VERSION}`;
|
|
7
7
|
function formatFasedDisplayLine() {
|
|
8
8
|
return `${FASED_AGENT_NAME} ${FASED_DISPLAY_VERSION}`;
|
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
03f1c6c4f9975b6d14e5cf7e79d871c44fab07eb079c05ec45b191f8eab384cd
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//#region src/channels/delivery.ts
|
|
2
|
+
const CHANNEL_DELIVERIES = [
|
|
3
|
+
"official-addon",
|
|
4
|
+
"bundled",
|
|
5
|
+
"source-only",
|
|
6
|
+
"external-prerequisite"
|
|
7
|
+
];
|
|
8
|
+
const CHANNEL_DELIVERY_ENTRIES = [
|
|
9
|
+
...[
|
|
10
|
+
"telegram",
|
|
11
|
+
"whatsapp",
|
|
12
|
+
"discord",
|
|
13
|
+
"slack",
|
|
14
|
+
"feishu",
|
|
15
|
+
"googlechat"
|
|
16
|
+
].map((id) => ({
|
|
17
|
+
id,
|
|
18
|
+
docsPath: `/channels/${id}`,
|
|
19
|
+
delivery: "official-addon"
|
|
20
|
+
})),
|
|
21
|
+
...[
|
|
22
|
+
"irc",
|
|
23
|
+
"line",
|
|
24
|
+
"mattermost",
|
|
25
|
+
"msteams",
|
|
26
|
+
"nextcloud-talk",
|
|
27
|
+
"synology-chat",
|
|
28
|
+
"zalo",
|
|
29
|
+
"zalouser"
|
|
30
|
+
].map((id) => ({
|
|
31
|
+
id,
|
|
32
|
+
docsPath: `/channels/${id}`,
|
|
33
|
+
delivery: "bundled"
|
|
34
|
+
})),
|
|
35
|
+
...[
|
|
36
|
+
"matrix",
|
|
37
|
+
"nostr",
|
|
38
|
+
"tlon",
|
|
39
|
+
"twitch"
|
|
40
|
+
].map((id) => ({
|
|
41
|
+
id,
|
|
42
|
+
docsPath: `/channels/${id}`,
|
|
43
|
+
delivery: "source-only"
|
|
44
|
+
})),
|
|
45
|
+
...[
|
|
46
|
+
"signal",
|
|
47
|
+
"imessage",
|
|
48
|
+
"bluebubbles"
|
|
49
|
+
].map((id) => ({
|
|
50
|
+
id,
|
|
51
|
+
docsPath: `/channels/${id}`,
|
|
52
|
+
delivery: "external-prerequisite"
|
|
53
|
+
}))
|
|
54
|
+
];
|
|
55
|
+
const DELIVERY_BY_ID = new Map(CHANNEL_DELIVERY_ENTRIES.map((entry) => [entry.id, entry]));
|
|
56
|
+
function listChannelDeliveryEntries() {
|
|
57
|
+
return CHANNEL_DELIVERY_ENTRIES.map((entry) => ({ ...entry }));
|
|
58
|
+
}
|
|
59
|
+
function getChannelDeliveryEntry(id) {
|
|
60
|
+
return DELIVERY_BY_ID.get(id.trim().toLowerCase());
|
|
61
|
+
}
|
|
62
|
+
function getChannelDelivery(id) {
|
|
63
|
+
return getChannelDeliveryEntry(id)?.delivery ?? "source-only";
|
|
64
|
+
}
|
|
65
|
+
function formatChannelDelivery(delivery) {
|
|
66
|
+
switch (delivery) {
|
|
67
|
+
case "official-addon": return "Official add-on";
|
|
68
|
+
case "bundled": return "Bundled";
|
|
69
|
+
case "source-only": return "Source-only";
|
|
70
|
+
case "external-prerequisite": return "External prerequisite";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function channelDeliveryAllowsInstall(delivery) {
|
|
74
|
+
return delivery === "official-addon" || delivery === "bundled";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { channelDeliveryAllowsInstall, formatChannelDelivery, getChannelDelivery };
|