@fased/fased 0.1.58 → 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/custom-api-registry.js +21 -0
- package/dist/agents/google-transport-stream.js +543 -0
- 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/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-CpgQGqe6.js → app-S_jg-ADS.js} +1706 -1675
- package/dist/control-ui/assets/{index-DiBBflpv.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-BJuN64m-.js → accounts-DxblobYM.js} +1 -1
- package/dist/plugin-sdk/{actions-DaEvM9Bl.js → actions-D4UNimWa.js} +2 -2
- package/dist/plugin-sdk/{active-listener-B8Kuanet.js → active-listener-CFuy106s.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-D7tCO0EH.js → audio-preflight-CxZixyhW.js} +25 -25
- package/dist/plugin-sdk/{audit-CVWH4BVP.js → audit-Cs0K7LBp.js} +1 -1
- package/dist/plugin-sdk/{channel-access-CH9FAS-I.js → channel-access-D5aHoTY8.js} +1 -1
- package/dist/plugin-sdk/{channel-access-configure-CI0je66H.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-01oBnQjh.js → chunk-B0FUGc5A.js} +1 -1
- package/dist/plugin-sdk/{chunk-items-D2zDJ8q8.js → chunk-items-Cy9a3X7x.js} +1 -1
- package/dist/plugin-sdk/command-status.js +25 -25
- package/dist/plugin-sdk/{commands-registry-ckg4fhYa.js → commands-registry-DmDRhRAU.js} +2 -2
- package/dist/plugin-sdk/{common-zHvdO8ly.js → common-CfUOowOp.js} +1 -1
- package/dist/plugin-sdk/{config-DrhYEiCM.js → config-mxULv0fQ.js} +1 -1
- package/dist/plugin-sdk/{config-schema-BtjeV5Hm.js → config-schema-D8E0LX8X.js} +4405 -460
- package/dist/plugin-sdk/device-pair.d.ts +1 -1
- package/dist/plugin-sdk/discord.d.ts +3 -3
- package/dist/plugin-sdk/discord.js +19 -19
- package/dist/plugin-sdk/{handle-action-5dhYpMbP.js → handle-action-DbVCF9HZ.js} +13 -13
- package/dist/plugin-sdk/{helpers-E9aafRzA.js → helpers-BXbdgs5H.js} +1 -1
- package/dist/plugin-sdk/{image-ops-D2U9ctmu.js → image-ops-D7jPxaph.js} +1 -1
- package/dist/plugin-sdk/index.d.ts +4 -4
- package/dist/plugin-sdk/index.js +27 -27
- package/dist/plugin-sdk/{login-hql0fNuL.js → login-BRxww6nv.js} +3 -3
- package/dist/plugin-sdk/{login-qr-DJJ0svux.js → login-qr-DJXsk9XH.js} +3 -3
- package/dist/plugin-sdk/{manager-ciNnAMBn.js → manager-Y2S_5IlI.js} +2 -2
- package/dist/plugin-sdk/{markdown-tables-BKxbua_h.js → markdown-tables-DHLFQqaF.js} +1 -1
- package/dist/plugin-sdk/{media-DUIZ6x9H.js → media-Czo4carg.js} +2 -2
- package/dist/plugin-sdk/{monitor-D-giXewh.js → monitor-CFHFAUOj.js} +30 -30
- package/dist/plugin-sdk/{monitor-CNSGw4uQ.js → monitor-xS9A8Upr.js} +29 -29
- package/dist/plugin-sdk/ollama-runtime.js +970 -0
- package/dist/plugin-sdk/{openresponses-http-dbTd8UMk.js → openresponses-http-BcUbeVV6.js} +25 -25
- package/dist/plugin-sdk/{optional-runtime-dependency-CKsJL1PD.js → optional-runtime-dependency-DdMbxS24.js} +1 -1
- package/dist/plugin-sdk/{outbound-DhGrjRft.js → outbound-Db8mRN6P.js} +6 -6
- package/dist/plugin-sdk/{outbound-attachment-DAF8huFz.js → outbound-attachment-BqFjcypb.js} +2 -2
- package/dist/plugin-sdk/{pairing-message-BsJVvXkb.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-DwM-BNbj.js → pairing-store-CQikgIbw.js} +2 -2
- package/dist/plugin-sdk/{pi-model-discovery-DkIdlJvJ.js → pi-model-discovery-CY3m5zJP.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-Cv7okUMt.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-Dxd87W3J.js → pw-ai-AFUqn-tQ.js} +3 -3
- package/dist/plugin-sdk/{replies-Bx61SvAC.js → replies-Fzh9PhXl.js} +2 -2
- package/dist/plugin-sdk/{resolve-outbound-target-bc-FpPZg.js → resolve-outbound-target-KpF3co6T.js} +1 -1
- package/dist/plugin-sdk/{resolve-route-D0eBYPtb.js → resolve-route-CDl74O19.js} +1 -1
- package/dist/plugin-sdk/{retry-policy-HTrC4zfC.js → retry-policy-D4uiqUOG.js} +1 -1
- package/dist/plugin-sdk/{runtime-BVkIrYLQ.js → runtime-Bb6KRnCC.js} +6 -4
- package/dist/plugin-sdk/{runtime-dependency-B2PqMdBu.js → runtime-dependency-DLDmB94f.js} +2 -2
- package/dist/plugin-sdk/sat-runtime.d.ts +2 -2
- package/dist/plugin-sdk/sat-runtime.js +25 -25
- package/dist/plugin-sdk/{send-DgzZUx2i.js → send-5nFktR1n.js} +5 -5
- package/dist/plugin-sdk/{send-DT2egZNK.js → send-Bfzf11VY.js} +7 -7
- package/dist/plugin-sdk/{send-BGDGzxUu.js → send-C4k4JuJN.js} +6 -6
- package/dist/plugin-sdk/{send-KJy3ajA3.js → send-D-uDKGIq.js} +6 -6
- package/dist/plugin-sdk/{send-C3QWSYLR.js → send-Du8ykP1k.js} +8 -8
- package/dist/plugin-sdk/{session-BCIEFOu1.js → session-CS-Td9EM.js} +2 -2
- package/dist/plugin-sdk/{skill-commands-CyIkcR8P.js → skill-commands-CFAlXWHk.js} +2 -2
- package/dist/plugin-sdk/{slack-DjKNh2uh.js → slack-DXYGbizH.js} +37 -37
- package/dist/plugin-sdk/{slack-actions-CeM9LWDp.js → slack-actions-BcMkNv1Z.js} +11 -11
- package/dist/plugin-sdk/slack.d.ts +3 -3
- package/dist/plugin-sdk/slack.js +9 -9
- package/dist/plugin-sdk/{sticker-cache-DcWzQ2wx.js → sticker-cache-Dr3rYfU1.js} +3 -3
- package/dist/plugin-sdk/{tables-B2iehyjG.js → tables-bFXyRpkx.js} +1 -1
- package/dist/plugin-sdk/{targets-BPket0SF.js → targets-DH7a9lKB.js} +1 -1
- package/dist/plugin-sdk/{telegram-actions-Cx_HWVht.js → telegram-actions-Besbw_Hg.js} +28 -28
- package/dist/plugin-sdk/telegram.d.ts +3 -3
- package/dist/plugin-sdk/telegram.js +8 -8
- package/dist/plugin-sdk/{thread-bindings.lifecycle-CYH69SIw.js → thread-bindings.lifecycle-CgOvvdw8.js} +3 -3
- package/dist/plugin-sdk/{thread-bindings.state-BN6461WG.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-vR-oNiBv.js → web-Q1-G--JH.js} +30 -30
- package/dist/plugin-sdk/{whatsapp-actions-BYNf8ceY.js → whatsapp-actions-BtSc2CBv.js} +13 -13
- package/dist/plugin-sdk/{whatsapp-heartbeat-DZwa8MF0.js → whatsapp-heartbeat-Bg9TuYzl.js} +2 -2
- package/dist/plugin-sdk/whatsapp.d.ts +3 -3
- package/dist/plugin-sdk/whatsapp.js +12 -12
- package/dist/plugin-sdk/{wsl-WGtdw_6h.js → wsl-C4DGFkOd.js} +3 -3
- 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 +6 -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 +6 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +6 -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 +6 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +6 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +6 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +6 -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,
|
|
@@ -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 };
|
|
@@ -2,6 +2,7 @@ import { CONFIG_DIR, isRecord, resolveUserPath } from "../../utils.js";
|
|
|
2
2
|
import { resolveFasedAgentPackageRootSync } from "../../infra/fased-root.js";
|
|
3
3
|
import { getPackageManifestMetadata } from "../../plugins/manifest.js";
|
|
4
4
|
import { discoverFasedAgentPlugins } from "../../plugins/discovery.js";
|
|
5
|
+
import { channelDeliveryAllowsInstall, getChannelDelivery } from "../delivery.js";
|
|
5
6
|
import fs from "node:fs";
|
|
6
7
|
import path from "node:path";
|
|
7
8
|
|
|
@@ -152,20 +153,22 @@ function buildCatalogEntry(candidate) {
|
|
|
152
153
|
if (!meta) {
|
|
153
154
|
return null;
|
|
154
155
|
}
|
|
156
|
+
const delivery = candidate.catalogSource === "official-catalog" ? "official-addon" : getChannelDelivery(id);
|
|
155
157
|
const install = resolveInstallInfo({
|
|
156
158
|
manifest,
|
|
157
159
|
packageName: candidate.packageName,
|
|
158
160
|
packageDir: candidate.packageDir,
|
|
159
161
|
workspaceDir: candidate.workspaceDir
|
|
160
162
|
});
|
|
161
|
-
if (!install) {
|
|
163
|
+
if (!install && channelDeliveryAllowsInstall(delivery)) {
|
|
162
164
|
return null;
|
|
163
165
|
}
|
|
164
166
|
return {
|
|
165
167
|
id,
|
|
166
168
|
meta,
|
|
169
|
+
delivery,
|
|
167
170
|
catalogSource: candidate.catalogSource,
|
|
168
|
-
install
|
|
171
|
+
install: channelDeliveryAllowsInstall(delivery) ? install ?? {} : {}
|
|
169
172
|
};
|
|
170
173
|
}
|
|
171
174
|
function buildExternalCatalogEntry(entry, catalogSource) {
|
|
@@ -201,7 +204,7 @@ function formatChannelPluginCatalogSource(source) {
|
|
|
201
204
|
}
|
|
202
205
|
}
|
|
203
206
|
function formatChannelPluginCatalogInstallBits(entry) {
|
|
204
|
-
const bits = [formatChannelPluginCatalogSource(entry.catalogSource)];
|
|
207
|
+
const bits = [entry.delivery, formatChannelPluginCatalogSource(entry.catalogSource)];
|
|
205
208
|
if (entry.install.expectedIntegrity) {
|
|
206
209
|
bits.push("integrity pinned");
|
|
207
210
|
}
|
|
@@ -211,10 +214,12 @@ function formatChannelPluginCatalogInstallBits(entry) {
|
|
|
211
214
|
return bits;
|
|
212
215
|
}
|
|
213
216
|
function formatChannelPluginCatalogSelectionHint(entry) {
|
|
214
|
-
|
|
217
|
+
const action = entry.delivery === "official-addon" ? "install" : entry.delivery === "bundled" ? "enable bundled" : "docs required";
|
|
218
|
+
return [...formatChannelPluginCatalogInstallBits(entry), action].join(" · ");
|
|
215
219
|
}
|
|
216
220
|
function formatChannelPluginCatalogStatusLine(entry) {
|
|
217
|
-
|
|
221
|
+
const next = entry.delivery === "official-addon" ? "install add-on to enable" : entry.delivery === "bundled" ? "enable bundled integration" : `follow ${entry.meta.docsPath}`;
|
|
222
|
+
return `${entry.meta.label}: ${formatChannelPluginCatalogInstallBits(entry).join(", ")}, ${next}`;
|
|
218
223
|
}
|
|
219
224
|
function buildChannelUiCatalog(plugins) {
|
|
220
225
|
const entries = plugins.map((plugin) => {
|